Spring 中的服务未使用 Junit 设置值
我正在使用 Junit 测试我的服务,但结果不是预期的。 当我保存实体时,返回日期未在服务中设置。
测试:
@Test
@DisplayName("Should set determined time for return date")
public void shouldSetReturnDate() {
ClientDTORequest dto = createNewDTOClient();
Client client = createNewClient();
Mockito.when(clientRepository.save(Mockito.any())).thenReturn(client);
Client saved = clientService.save(dto);
Assertions.assertEquals(dateTimeNow.plusMinutes(30), saved.getReturnDate());
}
我的createNewClient():
private Client createNewClient() {
//the null param is the return date
return new Client(1L, "name", null);
}
我的服务:
public Client save(ClientDTORequest dto) {
Client client = mapper.map(dto, Client.class);
client.setReturnDate(dateTimeNow.plusMinutes(30));
Client savedClient = clientRepository.save(client);
return savedClient;
}
当测试结果:
org.opentest4j.AssertionFailedError:
Expected :2022-04-04T01:17:25.715895900
Actual :null
结果没有被服务传递给mock时,这是我的镜头,但我不知道为什么。
谢谢!
Im testing my service with Junit but the result is not the expected.
When i save my entity, the return date is not setted in service.
Test:
@Test
@DisplayName("Should set determined time for return date")
public void shouldSetReturnDate() {
ClientDTORequest dto = createNewDTOClient();
Client client = createNewClient();
Mockito.when(clientRepository.save(Mockito.any())).thenReturn(client);
Client saved = clientService.save(dto);
Assertions.assertEquals(dateTimeNow.plusMinutes(30), saved.getReturnDate());
}
My createNewClient():
private Client createNewClient() {
//the null param is the return date
return new Client(1L, "name", null);
}
My service:
public Client save(ClientDTORequest dto) {
Client client = mapper.map(dto, Client.class);
client.setReturnDate(dateTimeNow.plusMinutes(30));
Client savedClient = clientRepository.save(client);
return savedClient;
}
And when the test result:
org.opentest4j.AssertionFailedError:
Expected :2022-04-04T01:17:25.715895900
Actual :null
The result is not passed by the service to mock, this is my shot, but i dont know why.
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
问题是您将其与“现在”相结合,因此该服务在运行时始终将有时间。
随着时间的推移,最好的工作方式之一是建模概念<代码>时钟或
timeProvider
并将其注入服务。然后,您可以模拟它以断言测试中的时间。注意:请注意在您的服务中保持状态,以免线程安全。因此,当“同时”进行多个服务电话时,您最终会出现并发问题。
The problem is you're coupled to "now", so the service always will have the time at the moment it runs.
One of the best ways of work with time is by modeling the concept
Clock
orTimeProvider
and injecting it to the Service. Then you can mock it to assert the time in the test.Note: Be careful about holding state in your service, so it's not thread safe. So, you'll end up with concurrency problems when multiple calls to service occurs "at the same time".
如果您使用 @Autowired 注入 clientRepository 那么它不会模拟。尝试@SpyBean
(@Autowired ClientRepository clientRepository 不会模拟;@SpyBean ClientRepository clientRepository 应该模拟)
If you injected your clientRepository with @Autowired then it won't mock. Try @SpyBean
(@Autowired ClientRepository clientRepository wouldn't mock; @SpyBean ClientRepository clientRepository should mock)
经过几个小时的测试,我发现了问题:
我的服务正在更改数据,但我的模拟 :
我找到了参数captor ,我可以从方法中获取对象致电:
声明绑架者:
使用测试方法:
After some hours of testing i found the problem:
My service was changing data, but was overridden by my mock:
So i found ArgumentCaptor, where i can get the object from method call:
Declaring the Captor:
Using at test method: