有没有办法使用 Mockito 来模拟类中的某些方法,而不是其他方法?
例如,在这个(诚然做作的)Stock类中,我想模拟getPrice()和getQuantity()返回值(如下面的测试片段所示),但我希望getValue()执行Stock类中编码的乘法
Stock
getPrice()
getQuantity()
getValue()
public class Stock { private final double price; private final int quantity; Stock(double price, int quantity) { this.price = price; this.quantity = quantity; } public double getPrice() { return price; } public int getQuantity() { return quantity; } public double getValue() { return getPrice() * getQuantity(); } @Test public void getValueTest() { Stock stock = mock(Stock.class); when(stock.getPrice()).thenReturn(100.00); when(stock.getQuantity()).thenReturn(200); double value = stock.getValue(); // Unfortunately the following assert fails, because the mock Stock getValue() method does not perform the Stock.getValue() calculation code. assertEquals("Stock value not correct", 100.00*200, value, .00001); }
要直接回答您的问题,是的,您可以模拟某些方法而不模拟其他方法。这称为 部分模拟 。有关更多信息,请参阅有关部分模拟的 Mockito 文档。
对于您的示例,您可以在测试中执行以下操作:
Stock stock = mock(Stock.class); when(stock.getPrice()).thenReturn(100.00); // Mock implementation when(stock.getQuantity()).thenReturn(200); // Mock implementation when(stock.getValue()).thenCallRealMethod(); // Real implementation
在这种情况下,每个方法实现都会被模拟,除非thenCallRealMethod()在when(..)子句中指定。
thenCallRealMethod()
when(..)
也有可能使用 spy 而不是 mock :
Stock stock = spy(Stock.class); when(stock.getPrice()).thenReturn(100.00); // Mock implementation when(stock.getQuantity()).thenReturn(200); // Mock implementation // All other method call will use the real implementations
在这种情况下,所有方法实现都是真实的,除非您使用when(..).
when(Object)当您像上一个示例一样使用 spy时,有一个重要的陷阱。将调用真正的方法(因为stock.getPrice()之前when(..)在运行时进行了评估)。如果您的方法包含不应调用的逻辑,这可能是一个问题。您可以像这样编写前面的示例:
when(Object)
stock.getPrice()
Stock stock = spy(Stock.class); doReturn(100.00).when(stock).getPrice(); // Mock implementation doReturn(200).when(stock).getQuantity(); // Mock implementation // All other method call will use the real implementations
另一种可能是使用org.mockito.Mockito.CALLS_REAL_METHODS,例如:
org.mockito.Mockito.CALLS_REAL_METHODS
Stock MOCK_STOCK = Mockito.mock( Stock.class, CALLS_REAL_METHODS );
这将未存根的调用委托给实际实现。
但是,对于您的示例,我相信它仍然会失败,因为实现getValue()依赖于quantityand price,而不是getQuantity()and getPrice(),这是您所嘲笑的。
quantity
price
另一种可能性是完全避免模拟:
@Test public void getValueTest() { Stock stock = new Stock(100.00, 200); double value = stock.getValue(); assertEquals("Stock value not correct", 100.00*200, value, .00001); }