[英]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);
}
}
有几个问题:
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 测试套件模拟实例,因为它不再需要。
@ExtendWith
注释的使用检查您的导入,我假设您在此处使用 JUnit 5。 确保您实际使用org.junit.jupiter.api
中的其他类(例如@Test
和Assertions
)。 默认情况下,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.