java - 试图在模拟服务上验证来自抽象类的方法调用,但我得到了一个 npe
问题描述
我在测试方法上坚持了几个小时。
我试图重现类似的情况。我有一个服务,它使用这样的实用方法扩展抽象服务:
public class MyService extends MyAbstractService {
@Autowired
private UserRepository userRepository;
public void whatever(MyDTO myDTO) {
User user = this.userRepository.findByName(myDTO.userId);
hello(user.name);
}
}
abstract class MyAbstractService {
protected void hello(String userName) {
System.out.printf("Hello %s", userName);
}
}
我的测试课:
@Test
void whenIcallWhaterver() {
MyService myService = Mockito.mock(MyService.class, InvocationOnMock::callRealMethod);
myService.whatever(myDTO);
verify(myService, only()).hello(anyString());
}
我的目标只是验证当我进入方法时,是否也调用了抽象服务的方法。我得到一个空指针异常,因为存储库不是在模拟中初始化(我假设是正常行为),但我想学习/了解如何测试它。
我该怎么做才能解决这个问题?
谢谢你的帮助
解决方案
您收到 NullPointerException 是因为您没有将 UserRepository 对象设置为 MyService。
请注意,您的测试没有加载任何弹簧上下文,因此注释 @Autowired 没有生效。
因此,为了让您的测试正常工作:
- 通过构造函数或设置器将模拟 UserRepository 添加到您的服务
- 或将弹簧上下文加载到您的测试中并添加模拟 UserRepository。
例如,您可以执行以下操作:
@SpringBootTest(classes = MyTestConfig.class)
class MyTest {
@MockBean
private UserRepository userRepository;
@SpyBean
private MyService myService;
@Test
void whenIcallWhaterver() {
// Mocks the response of the userRepository
final User user = new User();
user.setName("my-name");
Mockito.when(this.userRepository.findByName(Mockito.anyString()))
.thenReturn(user);
final MyDTO myDTO = new MyDTO();
myDTO.setUserId("myid");
this.myService.whatever(myDTO);
verify(this.myService).hello("my-name");
}
@Configuration
static class MyTestConfig {
@Bean
public MyService myService() {
return new MyService();
}
}
}
推荐阅读
- javascript - 如何向数据库中的所有用户发送网络推送?
- python - 以 Stripe 的方式实例化 Python 类
- python - 我知道 map 返回一个迭代器,但是我们如何将迭代器分配给 a 和 b?
- javascript - Javascript选择变量
- rust - Tokio 任务在完成前退出
- javascript - 有人可以向我解释这段代码吗?
- html - 完整尺寸的背景图像,但屏幕的第二半仍然是空的
- react-native - 网络请求与表单数据反应原生获取失败
- python - 显示 0.66 相关性的两个值,但图表完全不同
- java - Spring Security @PreAuthorize ByPass 用于特定角色