52

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

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

有没有一种方法,只是为了在我之后进行清理,以防在我的测试之后运行的其他一些测试也使用相同的实例并且可能执行他们没有要求模拟的模拟方法来取消模拟方法?

假设我有一个名为“wareHouseSpy”的间谍对象

说我重写了方法isSomethingMissing

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

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

就像是

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

或者可能

Mockito.unmock(wareHouseSpy)

谁知道?我在那个区域找不到任何东西

谢谢!

阿萨夫

4

7 回答 7

53

我认为

Mockito.reset(wareHouseSpy)

会做的。

于 2011-11-14T14:43:33.167 回答
18

假设您的大多数测试都使用存根响应。然后你会有一个如下所示的 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();
}
于 2016-02-16T00:46:00.257 回答
11

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

  • JUnit 为每个测试方法创建一个自己的新实例。您基本上不必担心重置模拟。
  • Mockito.reset(mockA, mockB, ...)使用 TestNG,您必须使用 an@BeforeMethod或 an重置模拟@AfterMethod
于 2011-11-14T19:50:18.163 回答
4

“正常”方法是在“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
  ...
}
于 2011-11-14T16:55:10.480 回答
3

也许我没有关注,但是当你有一个真实的对象时real

Object mySpy = spy(real);

然后“ unspymySpy......只需使用real.

于 2011-11-14T14:42:54.657 回答
0

专门针对这件作品:

有没有一种方法,只是为了在我之后进行清理,以防在我的测试之后运行的其他一些测试也使用相同的实例并且可能执行他们没有要求模拟的模拟方法来取消模拟方法?

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

于 2011-11-14T16:01:12.627 回答
-1

根据文档,我们有

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

于 2020-07-10T03:07:11.813 回答