【问题标题】:Why create a mock object using a framework instead of creating the object itself [duplicate]为什么使用框架创建模拟对象而不是创建对象本身[重复]
【发布时间】:2012-08-13 11:15:42
【问题描述】:

可能重复:
What is Object Mocking and when do I need it?

为什么要使用

创建模拟对象
MyObject myOb = Mockito.mock(MyObject.class);

什么时候可以改用:

MyObject myOb = new MyObject();

    public class MyObject(){
       private String str;
       //getters and setters
    }

如果上面的对象变得更复杂并且它与其他对象有依赖关系,我还需要为这些对象创建模拟对象。因此,如果需要设置所有成员来测试对象,为什么不直接创建对象而不是使用框架模拟它呢?

【问题讨论】:

  • 因为code.google.com/p/mockito 描述了 Mockito 在普通对象之上所做的事情。
  • 因为模拟框架提供了比普通对象更多的功能、表现力、存根、验证、回调等。有了这些,在单元测试中你现在更关注协作者之间的交互,这意味着你可以去进一步在不同的场景下测试不同的执行路径,即它有助于覆盖你的代码。

标签: java mockito


【解决方案1】:

只需比较您在示例中编写的行数。当然,你可以手动编写所有的模拟,但是你会做更多的输入,而且你的测试的可读性会降低。

【讨论】:

  • 另外,考虑一下当您的对象有 20 多个方法但您只对模拟其中的 一个(或其中几个)感兴趣时。创建一个模拟对象:还是 1 行,自己写:很多行。
  • @Björn Pollex 我在示例中写的行数是相同的 - 每一行
  • 也许我误解了什么。看起来你在写 MyObject-class 专门用作模拟。假设您需要一个用于测试的接口的实现,但您还没有一个(例如,您需要来自您正在为其编写测试的库的用户的回调)。这就是嘲笑可以帮助你的地方。你可以让一个模拟框架来处理这个,而不是仅仅为测试编写一个实现。这就是我在回答中的意思。
  • @Björn Pollex 感谢您的澄清。我刚刚写了 MyObject 来展示它是如何实现的。
  • +1 表示“...测试的可读性会降低。”。我希望能够阅读测试,并查看我所有的存根 (when( something ).thenReturn( something );) - 并且知道它是存根;接下来是调用任何正在测试的代码,然后是验证或断言(verify( something ).something();),但是如果我有很多手动交互,这些交互并不明显存根和验证,我的测试会更难理解。
【解决方案2】:

当你模拟某些东西时,你也可以断言某些事情发生了,比如你可以断言一个方法被调用了参数等等。

你不能使用具体的类来做到这一点

【讨论】:

  • 你可以用一个具体的类来做到这一点,但你必须手动为其编写逻辑。模拟框架实际上只是方便 - 但很多
  • 你可以,但你必须为每个场景创建一个 concete 类。在我看来模拟一个类更容易,因为你只需要模拟你正在测试的场景,其他方法、属性等可以忽略
【解决方案3】:

如果您问这个问题,那么您从未遇到过复杂到需要模拟的测试场景。当然,如果您的类足够简单且独立,您可以通过简单地实例化它们来测试它们,那么您应该这样做。

但是,在许多实际案例中,您希望测试依赖于其他类的类,而在单元测试场景中不可能(或不希望)实例化它们。可能是它们与外部服务或数据库进行通信。可能是它们具有您必须实例化的一长串附加依赖项。

还要记住,单元测试是关于隔离特定的计算单元并验证它们是否独立运行。模拟是一种很好的方法,它允许您从测试中删除依赖项。有效地说“假设依赖项 A 返回 Y,验证此方法返回 X(并且使用这些参数调用依赖项 A)。

【讨论】:

    猜你喜欢
    • 2010-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多