Mockito 与工厂进行条件验证

发布于 2024-10-06 17:52:01 字数 735 浏览 6 评论 0原文

在mockito中是否可以根据模拟是否实际在被测单元中使用来验证模拟上调用的方法?

举一个简单的例子,我向我的被测单元提供一个模拟工厂(FooFactory),当调用 Foo.create() 时,它返回一个模拟(Foo),供被测单元中的某些方法使用。测试。如何验证仅当被测单元调用 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。显然,我可以将验证添加到我知道需要 Reader 的每个测试中,但这似乎需要大量重复工作。

Is it possible in mockito to verify a method was called on a mock based on whether the mock was actually used in the unit-under-test?

For a simple example, I supply a mock factory (FooFactory) to my unit-under-test, and when Foo.create() is called, it returns a mock (Foo) to be used by certain methods in the unit-under-test. How can I verify that Foo.method() is called only if Foo.create() was called by the unit-under-test?

I'm envisioning that the code would look something like this:

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

For a little more concrete example, my factory returns a Reader object that I want to ensure is closed, but not every method in the class actually constructs a Reader. I could obviously add the verification to every test where I know the Reader is needed, but that seems like a lot of duplicated effort.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

余厌 2024-10-13 17:52:01

您确定要编写此测试吗?

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

1)您确实想确保资源被创建和关闭,因此尝试编写一个测试,您可以在其中验证两个方法调用。

2) 您要确保每当资源打开时,它也会关闭。这可以在生产代码中作为断言来实现...

如果您确实想继续使用您的方法,则可以捕获第一个验证在尚未调用 create() 方法时抛出的异常。在捕获中你只需返回即可。

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

Are you sure that you want to write this test?

I can see two solutions:

1) You really want to make sure that the resource gets created and closed, so try to write a test, where you can verify both method calls.

2) You want to make sure that whenever the resource is opened, it is also closed. This could be implemented as an assertion in the production code...

If you really want to go ahead with your approach, you could catch the exception that the first verify throws if the create() method hasn't been called. In the catch you just return.

Also you shouldn't do the verification in the cleanup, but in the actual test method.

初见 2024-10-13 17:52:01

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

因此,我建议将您的测试分成多个测试,每个场景一个测试,然后看看您是否仍然需要这个。

Honestly it sounds like your test is tooo complicated. It's been my experience of many projects and lots of unit testing that the best way to handle things is to ensure that each test tests one thing only. You can have as many asserts as you like, but it should be one method being called and one scenario tested. Anything mo and the test becomes too complex. Plus it makes it very hard for other developers to pick up the test at a later stage when developing the app further.

So I'd suggest breaking your test up into multiple tests, one per scenario and then see if you still need this.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文