mockito:如何取消模拟方法?

时间:2011-11-14 14:33:07

标签: java testing mockito spy

我有一个 JUnit 类,它有不同的方法来执行不同的测试。

我使用 Mockito 在真实实例上创建间谍,然后覆盖一些与我执行的实际测试无关的方法。

有没有办法,只是为了清理我以防万一我的测试后运行的其他一些测试也使用相同的实例,可能会执行一个模拟的方法,他们没有要求模拟,取消模拟方法?

说我有一个名为'wareHouseSpy'

的间谍对象

说我重写方法 isSomethingMissing

doReturn(false).when(wareHouseSpy).isSomethingMissing()

什么是正确的方法来取消覆盖,并使间谍恢复正常,即下一次启动 isSomethingMissing 来运行真正的方法?

类似

doReturn(Mockito.RETURN_REAL_METHOD).when(wareHouseSpy).isSomethingSpy()

或者

Mockito.unmock(wareHouseSpy)
谁知道?我在该地区找不到任何东西

谢谢!

阿萨弗

7 个答案:

答案 0 :(得分:37)

我认为

Mockito.reset(wareHouseSpy)

会这样做。

答案 1 :(得分:9)

假设您的大多数测试使用存根响应。然后你会有一个如下所示的setUp()方法:

@Before
public void setUp() {
  wareHouseSpy = spy(realWarehouse);
  doReturn(false).when(wareHouseSpy).isSomethingMissing();
}

现在假设您要撤消存根响应并在一次测试中使用实际实现:

@Test
public void isSomethingMissing_useRealImplementation() {
  // Setup
  when(wareHouseSpy.isSomethingMissing()).thenCallRealMethod();

  // Test - Uses real implementation
  boolean result = wareHouseSpy.isSomethingMissing();
}

答案 2 :(得分:7)

这取决于您是使用TestNG还是JUnit进行测试。

  • JUnit为每个测试方法创建一个新的自身实例。你基本上不必担心重置模拟。
  • 使用TestNG,您必须在Mockito.reset(mockA, mockB, ...)@BeforeMothod
  • 中使用@AfterMethod重置模拟

答案 3 :(得分:3)

也许我没有关注,但是当你有一个真实的物体real时:

Object mySpy = spy(real);

然后到" unspy " mySpy ...只需使用real

答案 4 :(得分:2)

“正常”方式是在“setUp”方法中重新实例化。但是,如果由于某种原因你有一个构建成本昂贵的真实对象,你可以这样做:

public class MyTests {

  private static MyBigWarehouse realWarehouse = new MyBigWarehouse();
  private MyBigWarehouse warehouseSpy;

  @Before
  public void setUp() {
    warehouseSpy = spy(realWarehouse); // same real object - brand new spy!
    doReturn(false).when(wareHouseSpy).isSomethingMissing();
  }

  @Test
  ...

  @Test
  ...

  @Test
  ...
}

答案 5 :(得分:0)

具体解决这篇文章:

  

有没有办法,只是为了清理我以防万一我的测试后运行的其他一些测试也使用相同的实例,可能会执行一个模拟的方法,他们没有要求模拟,取消模拟方法?

如果您正在使用JUnit,最简单的方法是使用@Before@After(其他框架具有等价物)并重新创建实例和间谍,以便任何测试都不依赖于或者是受到你在任何其他测试中所做的任何事情的影响。然后,您可以在每个测试内部执行spy / mock的特定于测试的配置。如果由于某种原因您不想重新创建对象,则可以重新创建间谍。无论哪种方式,每个人每次都从一个新鲜的间谍开始。

答案 6 :(得分:-1)

根据documentation,我们有

reset(mock);
//at this point the mock forgot any interactions & stubbing

文档进一步说明

通常,您无需重置模拟,只需创建新的模拟 对于每种测试方法。代替#reset(),请考虑编写 冗长,过度指定的简单,小型和集中测试方法 测试。

这是他们的github存储库中的一个示例,用于测试此行为并使用它:

@Test
public void shouldRemoveAllInteractions() throws Exception {
        mock.simpleMethod(1);
        reset(mock);
        verifyZeroInteractions(mock);
}

引用:ResetTest.java