繁体   English   中英

Null 指针异常 JUnit Mockito

[英]Null Pointer Exception JUnit Mockito

我是 JUnit 和 Mockitio 的新手。 当我运行以下代码时,我得到java.lang.NullPointerException: Cannot invoke "org.springframework.http.ResponseEntity.getStatusCodeValue()" 因为返回值 "com.learnit.testing.MyController.getUser(java.lang .Long)" 为 null

@Controller
@RequestMapping("/api")
public class MyController {

    @Autowired
    private MyService service;

    @GetMapping("/")
    @ResponseBody
    public ResponseEntity<Object> getUser(Long id) throws Exception {
        return service.myResponse(id);
    }
}

@Service
public class MyService {
    
    @Autowired
    private MyRepository repository;

    public ResponseEntity<Object> myResponse(Long id) throws Exception{

        MyData data=repository.findById(id).orElse(null);
        if(data!=null)
            return new ResponseEntity<>(HttpStatus.OK);
        return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);

    }
}

测试

@ExtendWith(MockitoExtension.class)
public class MyTest {

    @InjectMocks
    private MyController controller;
    
    @Mock
    private MyRepository repo;
    
    @Mock
    private MyService service;
    
    @Test
    public void checkService() throws Exception {
        when(repo.findById((long)1)).thenReturn(null);
        assertEquals(controller.getUser((long)1).getStatusCodeValue(), 500);
        
    }
}

有几个问题:

  1. 您没有存根MyService#myResponse方法的行为。 您需要模拟MyService实例,因为这是MyController实例的直接依赖项。 因此, MyRepository不需要在这个测试用例中进行模拟(除非您出于某种原因想要存根它的方法,但我在当前代码中没有这样做)。 我建议您更换以下内容:
        when(repo.findById((long)1)).thenReturn(null);

使用MyService模拟实例的存根行为:

        when(service.myResponse(1L)).thenReturn(new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR));

执行此操作时,可以删除 MyRepository 测试套件模拟实例,因为它不再需要。

  1. 根据@ExtendWith注释的使用检查您的导入,我假设您在此处使用 JUnit 5。 确保您实际使用org.junit.jupiter.api中的其他类(例如@TestAssertions )。 默认情况下,JUnit 不支持与 JUnit 4 的向后兼容性。不过,我想保持兼容性,应该在测试运行时路径中包含junit-vintage-engine工件。

PS您需要考虑您实际想要测试哪个 class ,这决定了应该模拟哪些实例。

恕我直言,您需要在测试 class 中添加注释的@RunWith(some.mockito.TestSuiteIDontRememberName.class) @Mock注解需要一个测试套件来搜索注解并收集信息以在其中注入值。

如果我是你,我会首先尝试在@Before方法中初始化模拟实例并查看测试是否运行......然后,我会阅读 Mockito (对不起,但我通常使用EasyMock )库文档,并且检查@Mock注释是如何使用的(我可以告诉你你有机会成为问题)

并且您的测试代码中存在问题......您正在告诉模拟实例在调用方法findById()时返回null ,所以很可能如果发生这种情况,当您尝试使用.orelse()方法。 可能您不知道要返回什么,或者您需要返回一个同样模拟的 object 实例......但因此,如果不实现与您的意图完全不同的东西,就不可能修复您的代码。

无论如何,您已经在代码中消除了足够多的东西以使其无法测试,并且在此过程中您根本没有包括如何调用要测试的方法。

请阅读如何创建一个最小的、可重现的示例页面并编辑您的问题以包含可测试的代码,以显示 NPE,因此我们至少可以看到它是如何发生的以及发生在何处。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM