我用 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
結果沒有通過服務來模擬,這是我的鏡頭,但我不知道為什么。
謝謝!
uj5u.com熱心網友回復:
問題是你被耦合到“現在”,所以服務總是在它運行的那一刻有時間。處理時間的最佳方法之一是對概念進行建模Clock或TimeProvider將其注入到服務中。然后你可以模擬它來斷言測驗中的時間。
class Clock {
LocalDateTime now() {
return LocalDateTime.now().plusMinutes(30); // <-- as you needs
}
}
class Service {
private Clock clock;
Service(Clock clock) {
this.clock = clock;
}
void save(MyEntity entity) {
entity.setCreatedDateTime(clock.now());
//repositoty.save(entity);
}
}
@Getter
class MyEntity {
private LocalDateTime createdDateTime;
public void setCreatedDateTime(LocalDateTime createdDateTime) {
//assing it to a field
this.createdDateTime = createdDateTime;
}
}
class ServiceTest {
@Mock
private Clock clock;
private Service service;
@Test
void testSave() {
LocalDateTime fixedDateTimeNow = LocalDateTime.of(2022, 4, 3, 18, 0, 0);
Mockito.when(clock.now()).thenReturn(fixedDateTimeNow);
MyEntity entity = new MyEntity();
service.save(entity);
Assertions.assertEquals(fixedDateTimeNow, entity.getCreatedDateTime());
}
}
注意:在服務中保持狀態時要小心,所以它不是執行緒安全的。因此,當多個服務呼叫“同時”發生時,您最終會遇到并發問題。
uj5u.com熱心網友回復:
如果您使用 @Autowired 注入了您的 clientRepository,那么它不會模擬。試試@SpyBean(@Autowired ClientRepository clientRepository 不會模擬;@SpyBean ClientRepository clientRepository 應該模擬)
uj5u.com熱心網友回復:
經過幾個小時的測驗,我發現了問題:
我的服務正在更改資料,但被我的模擬覆寫:
Mockito.when(clientRepository.save(Mockito.any())).thenReturn(client); <-- mock overridden the changed data from service
Client saved = clientService.save(dto);
所以我找到了ArgumentCaptor,我可以從方法呼叫中獲取物件:
宣布俘虜:
@Captor
ArgumentCaptor<Client> clientCaptor;
使用 at 測驗方法:
Mockito.when(clientRepository.save(clientCaptor.capture())).thenReturn(client); //<-- capturing the result
clientService.save(dto);
Client saved = clientCaptor.getValue() //getting object
Assertions.assertEquals(dto.getReturnDate().plusMinutes(30), saved.getReturnDate()); //assertion
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/457274.html
