为了账号安全,请及时绑定邮箱和手机立即绑定

使用Mockito来模拟一些方法而不是其他方法

使用Mockito来模拟一些方法而不是其他方法

www说 2019-08-09 14:42:55
使用Mockito来模拟一些方法而不是其他方法有没有办法,使用Mockito来模拟一个类中的某些方法,而不是其他方法?例如,在这个(公认的设计)Stock类中我想模拟getPrice()和getQuantity()返回值(如下面的测试片段所示),但我希望getValue()执行在Stock中编码的乘法类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);}
查看完整描述

3 回答

?
30秒到达战场

TA贡献1828条经验 获得超6个赞

要直接回答你的问题,是的,你可以模拟一些方法而不会嘲笑其他方法。这称为部分模拟。有关详细信息,请参阅部分模拟的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(..)子句中指定,否则将模拟每个方法实现。


还有一种可能性与间谍相反而不是模拟:


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)与前一个例子中一样使用间谍时,有一个重要的陷阱。将调用真实方法(因为在运行stock.getPrice()之前进行评估when(..))。如果您的方法包含不应调用的逻辑,则可能会出现问题。您可以像这样编写上一个示例:


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,例如:


Stock MOCK_STOCK = Mockito.mock( Stock.class, CALLS_REAL_METHODS );

这会将未经调用的调用委托给实际实现。


然而,随着你的榜样,我相信它仍然会失败,因为实施getValue()依赖于quantity和price,而不是getQuantity()和getPrice(),这是你嘲笑什么。


另一种可能性是完全避免模拟:


@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);

}


查看完整回答
反对 回复 2019-08-09
?
DIEA

TA贡献1820条经验 获得超2个赞

根据文件:


Foo mock = mock(Foo.class, CALLS_REAL_METHODS);


// this calls the real implementation of Foo.getSomething()

value = mock.getSomething();


when(mock.getSomething()).thenReturn(fakeValue);


// now fakeValue is returned

value = mock.getSomething();


查看完整回答
反对 回复 2019-08-09
  • 3 回答
  • 0 关注
  • 877 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号