我正在嘗試為以下服務方法創建單元測驗:
public CompanyDTO update(CompanyRequest companyRequest, UUID uuid) {
final Company company = companyRepository.findByUuid(uuid)
.orElseThrow(() -> new EntityNotFoundException("Not found"));
company.setName(companyRequest.getName());
final Company saved = companyRepository.save(company);
return new CompanyDTO(saved);
}
我創建了以下單元測驗:
@InjectMocks
private CompanyServiceImpl companyService;
@Mock
private CompanyRepository companyRepository;
@Captor
ArgumentCaptor<Company> captor;
@Test
public void testUpdate() {
final Company company = new Company();
company.setName("Company Name");
final UUID uuid = UUID.randomUUID();
final CompanyRequest request = new CompanyRequest();
request.setName("Updated Company Name");
when(companyRepository.findByUuid(uuid))
.thenReturn(Optional.ofNullable(company));
when(companyRepository.save(company)).thenReturn(company);
CompanyDTO result = companyService.update(request, uuid);
/* here we get the "company" parameter value that we send to save method
in the service. However, the name value of this paremeter is already
changed before passing to save method. So, how can I check if the old
and updated name value? */
Mockito.verify(companyRepository).save(captor.capture());
Company savedCompany = captor.getValue();
assertEquals(request.getName(), savedCompany.getName());
}
據我所知,我們ArgumentCaptor用來捕獲傳遞給方法的值。在這個例子中,我需要在正確的時間捕獲值,并將發送到 update 方法的 name 的更新值與 update 后 name 屬性的回傳值進行比較。但是,我找不到如何正確測驗它并向我的測驗方法添加必要的注釋。那么,我應該如何使用ArgumentCaptor給定值(“更新的公司名稱”)來驗證我的更新方法更新公司。
uj5u.com熱心網友回復:
下面是我將如何撰寫此測驗用例,并將解釋作為代碼注釋。
@Test
public void testUpdate() {
// we make this a mock so we can analyze it later
final Company company = mock(Company.class);
// no need to have the same String literal twice
final String updatedName = "Updated Company Name";
// we make this a mock because only that one method is used
// if you create an actual object, you'll need to adjust this test
// when the constructor changes later
final CompanyRequest request = mock(CompanyRequest.class);
when(request.getName()).thenReturn(updatedName);
// we don't really care about the actual uuid, so any() will do here
when(companyRepository.findByUuid(any()))
.thenReturn(Optional.ofNullable(company));
when(companyRepository.save(company)).thenReturn(company);
// setup complete, let's go
CompanyDTO result = companyService.update(request, UUID.randomUUID());
// we want to make sure the name change has been applied
Mockito.verify(company.setName(udpatedName);
// make sure it has been saved as well
Mockito.verify(companyRepository).save(company);
// verify that the returned dto actually contains the company we've been working on
Company savedCompany = result.getCompany();
assertSame(savedCompany, company);
}
請注意,這并不能回答您關于如何使用引數捕獲器的實際問題,但那是因為這是一個 XY 問題。
uj5u.com熱心網友回復:
這是您的ArgumentCaptor.
被測代碼:
public void createProduct(String id) {
Product product = new Product(id);
repository.save(product);
}
請注意,a) 我們在測驗代碼中創建了一個物件,b) 我們想要驗證該物件的特定內容,以及 c) 在呼叫之后我們無權訪問該物件。這些幾乎就是您需要俘虜的確切情況。
你可以這樣測驗:
void testCreate() {
final String id = "id";
ArgumentCaptor<Product> captor = ArgumentCaptor.for(Product.class);
sut.createProduct(id);
// verify a product was saved and capture it
verify(repository).save(captor.capture());
final Product created = captor.getValue();
// verify that the saved product which was captured was created correctly
assertThat(created.getId(), is(id));
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/355984.html
