仅当传递给定 class 的任何 *non-null* 对象时才模拟方法 return 一个值
Mock method to return a value only when passed any *non-null* object of a given class
我正在使用 Mockito 模拟一个方法 return 给定日期时的日期。
when(supplier.calculateDeliveryDate(any(Date.class)))
.thenReturn(supplierDeliveryDate);
但是,当它传递一个 非空 日期对象时,我只希望它 return supplierDeliveryDate
。
当传递 null
时,它应该 return 为空。
这可能吗?我该怎么做?
使用 ArgumentMatchers.isNull()
匹配器。
when(supplier.calculateDeliveryDate(any(Date.class)))
.thenReturn(supplierDeliveryDate);
when(supplier.calculateDeliveryDate(isNull()))
.thenReturn(null);
您可以使用匿名内部 class:
// unit test
public OrderServiceTest {
// instance of class-under-test
private OrderService instance;
// stub value
private Date supplierDeliveryDate = new Date();
// mock as an anonymous inner class
private Supplier supplier = new Supplier() {
public Date calculateDeliveryDate(Date input) {
if (input == null) {
return null;
}
else {
return supplierDeliveryDate;
}
}
};
@Before
public void setUp() {
instance = new OrderService();
// dependency injection
instance.setSupplier(supplier);
}
@Test
public void testOrderHappy() {
// SETUP
Date orderDate = new Date();
// CALL
Date result = instance.order(orderDate);
// VERIFY
assertTrue(supplierDeliveryDate == result);
}
@Test
public void testOrderNull() {
// SETUP
Date orderDate = null;
// CALL
Date result = instance.order(orderDate);
// VERIFY
assertNull(result);
}
}
但你真的应该想知道为什么你需要这种行为。
如果您编写了一个定义良好的测试用例,那么您应该确切地知道您的 mock 被调用的频率和参数。如果是这样,那么您可以只存根预期的调用,而不是使用条件行为连接您的模拟。
请注意,如果您的测试尽可能 'sharp',这将很有用。如果调用模拟的次数与预期不同,或者使用不同的参数,则测试应该失败。
您可以使用辅助方法:
public static <T> void validateAndMock(Supplier<T> ongoingStubbing, T mockedResponse) {
if (mockedResponse != null) {
when(ongoingStubbing.get()).thenReturn(mockedResponse);
}
}
然后调用:
validateAndMock(() -> supplier.calculateDeliveryDate(any(Date.class)), supplierDeliveryDate);
我正在使用 Mockito 模拟一个方法 return 给定日期时的日期。
when(supplier.calculateDeliveryDate(any(Date.class)))
.thenReturn(supplierDeliveryDate);
但是,当它传递一个 非空 日期对象时,我只希望它 return supplierDeliveryDate
。
当传递 null
时,它应该 return 为空。
这可能吗?我该怎么做?
使用 ArgumentMatchers.isNull()
匹配器。
when(supplier.calculateDeliveryDate(any(Date.class)))
.thenReturn(supplierDeliveryDate);
when(supplier.calculateDeliveryDate(isNull()))
.thenReturn(null);
您可以使用匿名内部 class:
// unit test
public OrderServiceTest {
// instance of class-under-test
private OrderService instance;
// stub value
private Date supplierDeliveryDate = new Date();
// mock as an anonymous inner class
private Supplier supplier = new Supplier() {
public Date calculateDeliveryDate(Date input) {
if (input == null) {
return null;
}
else {
return supplierDeliveryDate;
}
}
};
@Before
public void setUp() {
instance = new OrderService();
// dependency injection
instance.setSupplier(supplier);
}
@Test
public void testOrderHappy() {
// SETUP
Date orderDate = new Date();
// CALL
Date result = instance.order(orderDate);
// VERIFY
assertTrue(supplierDeliveryDate == result);
}
@Test
public void testOrderNull() {
// SETUP
Date orderDate = null;
// CALL
Date result = instance.order(orderDate);
// VERIFY
assertNull(result);
}
}
但你真的应该想知道为什么你需要这种行为。
如果您编写了一个定义良好的测试用例,那么您应该确切地知道您的 mock 被调用的频率和参数。如果是这样,那么您可以只存根预期的调用,而不是使用条件行为连接您的模拟。
请注意,如果您的测试尽可能 'sharp',这将很有用。如果调用模拟的次数与预期不同,或者使用不同的参数,则测试应该失败。
您可以使用辅助方法:
public static <T> void validateAndMock(Supplier<T> ongoingStubbing, T mockedResponse) {
if (mockedResponse != null) {
when(ongoingStubbing.get()).thenReturn(mockedResponse);
}
}
然后调用:
validateAndMock(() -> supplier.calculateDeliveryDate(any(Date.class)), supplierDeliveryDate);