尝试在模拟服务上验证来自抽象 class 的方法调用,但我得到了一个 npe
Trying to verify a method call from abstract class on a mocked service but I get a 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);
}
}
我的测试class:
@Test
void whenIcallWhaterver() {
MyService myService = Mockito.mock(MyService.class, InvocationOnMock::callRealMethod);
myService.whatever(myDTO);
verify(myService, only()).hello(anyString());
}
我的目标只是验证当我进入任何方法时,抽象服务的方法是否也被调用。我得到一个空指针异常,因为存储库不是在模拟中初始化(我假设的正常行为),但我想 learn/understand 如何测试它。
我该如何解决这个问题?
感谢您的帮助
您收到 NullPointerException,因为您没有将 UserRepository 对象设置为 MyService。
请注意,您的测试未加载任何 spring 上下文,因此 @Autowired 注释未生效。
所以为了让你的测试工作:
- 通过构造函数或setter
向您的服务添加模拟 UserRepository
- 或将 spring 上下文加载到您的测试中并添加模拟 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();
}
}
}
我在一个测试方法上坚持了几个小时。
我试图重现类似的情况。我有一个服务使用这样的实用方法扩展抽象服务:
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);
}
}
我的测试class:
@Test
void whenIcallWhaterver() {
MyService myService = Mockito.mock(MyService.class, InvocationOnMock::callRealMethod);
myService.whatever(myDTO);
verify(myService, only()).hello(anyString());
}
我的目标只是验证当我进入任何方法时,抽象服务的方法是否也被调用。我得到一个空指针异常,因为存储库不是在模拟中初始化(我假设的正常行为),但我想 learn/understand 如何测试它。
我该如何解决这个问题?
感谢您的帮助
您收到 NullPointerException,因为您没有将 UserRepository 对象设置为 MyService。
请注意,您的测试未加载任何 spring 上下文,因此 @Autowired 注释未生效。
所以为了让你的测试工作:
- 通过构造函数或setter 向您的服务添加模拟 UserRepository
- 或将 spring 上下文加载到您的测试中并添加模拟 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();
}
}
}