什么时候避免嘲笑?

时间:2011-07-27 09:59:42

标签: java unit-testing mocking

模拟的最常见用例是

objA uses objB;
use objA without having objB populated/initialized

这样

@Mock
private UserInterface userInterface;

public void method() {
   MockitoAnnotations.initMocks(this);
   Client client;
   client.setUserInterface(userInterface);
   when(userInterface.getSomething()).thenReturn(new OutputType("f"));
   client.doSomething();
}

但是如果我们实际上只需要objA的OUTPUT怎么办? 假设我们不想调用返回SomeOutput的objA.doSomething();来获取SomeOutput,所以我们可以

  1. 为doSomething()模拟它以返回SomeOutput; - 没有多大意义

  2. 使用new SomeOutput(bla, bla, bla);填充变量,而不会嘲笑任何内容。

  3. 我问,因为我看到程序员嘲笑第二种方式,实际上没有意义,因为他们只是实例化new SomeOutput(bla, bla, bla);并通过模拟的objA返回它;

    它有任何秘密目的吗?我对嘲笑比较陌生。

2 个答案:

答案 0 :(得分:12)

当你想在组件之间测试交互时,模拟是很棒的。

当您不关心交互时,存根和假货很棒,但您希望一个组件能够向另一个组件提供数据。与使用模拟框架相比,这些最终可能需要更长时间才能创建,但随后编写更多测试通常会更容易。许多模拟框架也提供了存根功能。

对于已经过测试的足够简单的类型(通常提供数据而不是服务),只需使用真实类型。

请参阅Martin Fowler's articles on mocks and stubs了解更多启示。

答案 1 :(得分:1)

我不知道我是否有你,但我会尽力回答。 模拟的目标(您可能已经知道)是隔离您正在测试的代码段。一个单元测试(我假设我们正在讨论当有模拟时的单元测试) 应该只测试一件事。在您的示例中,您可以这样做:

 new SomeOutput(bla, bla, bla);

即使结果是相同的,你也会获得模拟对象,在这种情况下你不是要隔离你要测试的类,因为你“调用”一个依赖的组件代码

无论如何,我建议你看一下这本书

http://artofunittesting.com/

即使它在.net中,概念仍然是相同的