使用Mockito来模拟一些方法而不是其他方法 [英] Use Mockito to mock some methods but not others

查看:110
本文介绍了使用Mockito来模拟一些方法而不是其他方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法,使用Mockito来模拟一个类中的某些方法,而不是其他方法?

Is there any way, using Mockito, to mock some methods in a class, but not others?

例如,在这个(公平的做作)股票类我想要模拟getPrice()和getQuantity()返回值(如下面的测试片段所示),但我希望getValue()执行在Stock类中编码的乘法

For example, in this (admittedly contrived) Stock class I want to mock the getPrice() and getQuantity() return values (as shown in the test snippet below) but I want the getValue() to perform the multiplication as coded in the Stock class

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文档信息。

To directly answer your question, yes, you can mock some methods without mocking others. This is called a partial mock. See the Mockito documentation on partial mocks for more information.

对于您的示例,您可以在测试中执行以下操作:

For your example, you can do something like the following, in your test:

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(..)子句中。

In that case, each method implementation is mocked, unless specify thenCallRealMethod() in the when(..) clause.

有还有一种可能性另一种方式是间谍而不是模拟

There is also a possibility the other way arround with spy instead of 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

case,所有方法实现都是真实的,除非你用定义了一个模拟行为,当(..)

In that case, all method implementation are the real one, except if you have defined a mocked behaviour with when(..).

当你使用时,如果像前面的例子那样使用间谍(对象),则会有一个重要的陷阱。将调用真实方法(因为 stock.getPrice()之前评估时(...)在运行时) 。如果您的方法包含不应被调用的逻辑,则可能会出现问题。您可以像这样编写上一个示例:

There is one important pitfall when you use when(Object) with spy like in the previous example. The real method will be called (because stock.getPrice() is evaluated before when(..) at runtime). This can be a problem if your method contains logic that should not be called. You can write the previous example like this:

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






然而,在你的例子中,我相信它仍然会失败,因为 getValue()的实现依赖于数量价格,而不是 getQuantity() getPrice (),这就是你所嘲笑的。


However, with your example, I believe it will still fail, since the implementation of getValue() relies on quantity and price, rather than getQuantity() and getPrice(), which is what you've mocked.

你真正想要的只是:

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

这篇关于使用Mockito来模拟一些方法而不是其他方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆