Mockito与工厂的条件验证

时间:2010-12-09 19:38:25

标签: java unit-testing mockito

在mockito中是否有可能根据模拟是否实际用于被测单元来验证模拟调用方法?

举一个简单的例子,我向我的被测单元提供了一个模拟工厂(FooFactory),当调用Foo.create()时,它返回一个mock(Foo),供单元中的某些方法使用-under测试。只有在被测单元调用Foo.create()时,如何验证是否调用了Foo.method()?

我想到代码看起来像这样:

@Before
public void init() {
  Foo mockFoo = mock(Foo.class);
  when(fooFactory.create()).thenReturn(mockFoo);
  test = new UnitUnderTest(fooFactory);
}

@Test
... may or may not create a foo ...

@After
public void cleanup() {
  if (verify(fooFactory).create()) {  // Here's the 'conditional verification'
    Foo mockFoo = fooFactory.create();
    verify(mockFoo).close();
  }
}

对于一个更具体的例子,我的工厂返回一个我想要确保关闭的Reader对象,但并不是该类中的每个方法都实际构造了一个Reader。我显然可以将验证添加到我知道需要阅读器的每个测试中,但这似乎是很多重复的工作。

2 个答案:

答案 0 :(得分:1)

您确定要编写此测试吗?

我可以看到两种解决方案:

1)您确实希望确保创建和关闭资源,因此请尝试编写测试,以便验证两种方法调用。

2)您希望确保无论何时打开资源,它都会关闭。这可以作为生产代码中的断言来实现......

如果你真的想继续你的方法,你可以捕获第一个验证抛出的异常,如果没有调用create()方法。在捕获中你就回来了。

此外,您不应该在清理中进行验证,而是在实际的测试方法中进行验证。

答案 1 :(得分:0)

老实说,听起来你的测试太复杂了。这是我对许多项目和大量单元测试的经验,处理事情的最佳方法是确保每个测试只测试一件事。您可以拥有任意数量的断言,但它应该是一个被调用的方法和一个测试的场景。莫和测试变得太复杂了。此外,它使得其他开发人员在以后进一步开发应用程序时很难接受测试。

因此,我建议将您的测试分解为多个测试,每个方案一个,然后看看您是否还需要它。