【问题标题】:How can I test this method using Mockito?如何使用 Mockito 测试此方法?
【发布时间】:2017-08-18 14:38:30
【问题描述】:

我有一个方法,我想使用 Mockito 框架测试不同对象之间的复杂交互。我会很感激一些指导方针。我知道代码没有多大意义。

getInstance() 方法都是静态的。我想模拟 obj3 并使 if 语句在测试中返回 true。

public MyRequest getRequest(ObjectOne obj1, ObjectTwo obj2) {

    ObjectThree obj3 = FactoryOne.getInstance().getList().getObject(obj2.getId());


    if(FactoryTwo.getInstance().isFlagSet("flag")){
        ....
    }


    return new MyRequest(....);
}

【问题讨论】:

  • 也许包含该方法的类可以将两个工厂作为属性并从构造函数中获取它们,您可以使用该构造函数注入一些模拟来模拟 getList() 和 isFlagSet(...)。
  • “我知道代码意义不大”与其他一些相比,还不错。
  • 为什么首先要模拟obj3?测试不能简单地调用getRequest 并为obj1 和obj2 提供适当的值,然后检查返回的值吗?由于这个网站上有很多问题,这个问题来自XY problem。
  • 因为obj3可能是在访问db或者cache之后才构建的。
  • 那就顺其自然吧。相信我(因为我几乎每天都写这样的测试),如果你关心有好的/有用的测试,投资于访问数据库的集成测试要好得多,而不是试图“假装它直到你成功”(Kent Beck 的表达)。

标签: java testing mocking mockito


【解决方案1】:

实际上,为obj3 变量赋值所调用的方法是不可直接测试的。

根本原因是getInstance(),这是一个静态方法。

其实FactoryOne.getInstance()应该是被测类的依赖,返回的对象应该是接口

这样就可以定义一个设置依赖的构造函数了:

public MyClass(FooInterface foo){
   this.foo = foo;
}

并替换:

ObjectThree obj3 = FactoryOne.getInstance().getList().getObject(obj2.getId());

作者:

ObjectThree obj3 = foo.getList().getObject(obj2.getId());

在应用程序代码中,您可以调用构造函数:

MyClass c = new MyClass(FactoryOne.getInstance().getList());

并且在测试代码中,您可以为Foo 接口创建一个mock,通过构造函数将其设置为测试下的类:

Foo fooMock = Mockito.mock(Foo.class);
MyClass myClassUnderTest = new MyClass(fooMock);

然后为getList() 记录一个模拟行为,以在测试中将另一个具有调用所需值的模拟对象返回给getObject()。

【讨论】:

  • 你怎么知道在这种情况下模拟 obj3 是有意义的?即使它需要被嘲笑,它也可以完美地完成。因此,无论哪种方式,说getRequest 代码“不可测试”是不合理的。像这样的答案是没有好处的......
  • 在哪一点上,你可以肯定它没有意义? op 想知道如何模拟它的依赖关系。我向他解释。您至少可以正确引用我的话:“不可直接测试”并不意味着“不可测试”。
  • 因为 OP 从不描述实际问题是什么(这是一个“XY 问题”),只是 假设 没有明确的理由应该嘲笑 FactoryOne。并且代码 is “直接可测试”(如果需要,我可以使用两个不同的模拟库编写所述测试)。但实际上,很可能在这里使用任何模拟都是一个坏主意。我说了这么多年,经历了许多考验,并且看到嘲笑被滥用/滥用了这么多次......
  • OP 没有解释为什么要模拟依赖项这一事实并不意味着它不是必需的。我在测试方面也有很多经验,但我并没有得出零信息的结论,而只是因为我出于不好的原因而嘲笑我的糟糕经历。直接可测试的意思是:没有 powermock、没有 jmockit 等......在运行时没有字节码操作。
  • 我没有说不需要模拟它,我说我们不知道——尽管我想它真的不需要。 (实际上,OP 刚刚评论说依赖关系涉及一些数据库访问 - 这本身并不是模拟它的好理由,IMO。)您对除了您最喜欢的工具以外的工具表现出非理性的偏见。抱歉,但是像“运行时的字节码操作”这样的 cmets [很糟糕] 只是 FUD(如果您知道字节码操作是什么,则不合逻辑)。
猜你喜欢
  • 2015-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-14
  • 1970-01-01
  • 1970-01-01
  • 2021-11-06
  • 2012-02-03
相关资源
最近更新 更多