如何使用mockito的verify方法验证我的sendMessage方法是用Msg.保存还是用Msg.UPDATE调用的。
@Service
public class CustomerService {
private final CustomerRepository customerRepository;
private final SendMessageInTopic messageInTopic;
public CustomerService (CustomerRepository customerRepository, SendMessageInTopic messageInTopic)
{
this.customerRepository = customerRepository;
this.messageInTopic= messageInTopic;
}
public Customer saveCustomer(Customer savedCustomer) {
Customer customer = customerRepository
.findCustomerByEmail(savedCustomer.getEmail());
if(customer != null) {
customer.setFirstName(savedCustomer.getFirstName());
customer.setLastName(savedCustomer.getLastName());
customer.setPhoneNumber(savedCustomer.getPhoneNumber());
messageInTopic.sendMessage(savedCustomer.getId(),Msg.SAVE)
} else {
customer = new Customer();
customer.setFirstName(savedCustomer.getFirstName());
customer.setLastName(savedCustomer.getLastName());
customer.setEmail(savedCustomer.getEmail());
customer.setPhoneNumber(savedCustomer.getPhoneNumber());
messageInTopic.sendMessage(savedCustomer.getId(),Msg.Update)
}
return customerRepository.save(customer);
}
}
public class CustomerServiceTest{
private final CustomerRepository customerRepository = mock(CustomerRepository.class);
private final CustomerService customerService = mock(CustomerService.class);
private final SendMessageInTopic messageInTopic = mock(SendMessageInTopic.class);
private final CustomerMapper customerMapper = mock(CustomerMapper.class);
@Test
void whenSaveCustomerThenMsgSAVEOrUPDATE() {
// Given
final var customerId = "123456";
final var customer =
new CustomerDto(ensUserId, 'james', 'GREWAN', '32766666', '[email protected]');
final customerEntity = mock(Customer.class);
when(customerRepository.findCustomerByEmail(customer.getEmail())
.thenReturn(Optional.of(customerEntity));
when(customerRepository.save(customerEntity)).thenReturn(customerEntity);
when(customerMapper.toDto(customerEntity)).thenReturn(customer);
// When
final var result = customrService.saveCustomer(customer);
// Then
assertEquals(result, customer);
verify(messageInTopic, times(1)).sendMessage(result.getId(),Msg.SAVE);
}
}
verify(messageInTopic,times(1)).sendMessage(result.getId(),Msg.保存);:这是我将测试是否在create情况下使用Msg.保存参数或在update情况下使用Msg.UPDATE参数调用sendMessage方法的地方。
这个检查怎么做?
2条答案
按热度按时间lsmepo6l1#
@knittl是正确的。您的验证呼叫正确。问题是你在嘲笑你要测试的类。当你调用
mock(CustomerService.class)
时,Mockito实际上是在创建一个类,这个类会存根所有的方法(即覆盖它们并返回默认值):所以
customerService.saveCustomer(customer)
将返回null,因为customerService实际上是一个CustomerServiceMock。assertEquals(result, customer)
将因此失败。解决方案是将customerService = mock(CustomerService.class);
替换为customerService = new CustomerService(customerRepository, messageInTopic)
。注意,customerRepository和messageInTopic是您声明的模拟。但是,由于这些行,您的assertEqual仍然会失败。
这使得
saveCustomer(customer)
返回mockcustomerEntity
。assertEquals
失败,因为customerEntity
不匹配customer
。verify(messageInTopic ...
也不会工作,因为sendMessage(result.getId(),Msg.SAVE)
等效于sendMessage(null, Msg.SAVE)
。这是因为customerEntity
是一个mock(Customer.class)
,这意味着customerEntity.getId
看起来像这样:有很多方法可以解决这个问题。我的建议是删除
customerEntity
并像这样使用customer
:这将使saveCustomer返回
customer
,以便assertEqual通过。它还将使savedCustomer.getId()
和result.getId()
相等。findCustomerByEmail
无论如何都应该返回真实的客户,所以这对我来说最有意义。另外,作为FYI:Matchers.eq和直接使用参数在功能上是相同的,所以它不会改变任何东西:
那么为什么要使用Matchers.eq呢?假设您只想验证sendMessage是用Msg调用的。更新消息,你不关心id。问题是你不能混合匹配器和直接参数,所以这不起作用:
但这会起作用:
另外,作为第二个FYI,有许多不同的方法来验证参数。这里有一个关于所有不同方式的信息的帖子:Mockito. Verify method arguments。如果你想验证是对象的参数,这一点尤其重要。
6vl6ewon2#
有几种方法可以做到这一点。例如,使用captors:
首先在测试类中声明一个要检查的参数的捕获器:
然后在测试中,验证并Assert正确的值: