【问题标题】:Mocking instance method [duplicate]模拟实例方法[重复]
【发布时间】:2019-06-14 17:19:36
【问题描述】:

也许我遗漏了什么,谁能告诉我为什么这个单元测试用例不起作用?

谢谢。

import java.util.Random;


public class A {
    private B b;

    public A() {
        b = new B();
    }

    public int methodA() {
        return b.methodB();
    }

}

// 只返回一个随机数

class B {
    public int methodB() {
        return new Random().nextInt();
    }
}

// 这是我的测试方法,它不打印 20

    @Test
    public void testMethodA() {
        B b = Mockito.mock(B.class);
        Mockito.when(b.methodB()).thenReturn(20);

        A a = new A();
        System.out.println(a.methodA());
    }

【问题讨论】:

  • 模拟没有被插入A,所以A在你调用它的构造函数时仍然实例化一个新的B。一种常见的方法是将已经创建的B 传递给A 的构造函数。所以在你创建你的模拟之后,你可以做A a = new A(b);
  • 我总是很惊讶有多少人只是开始使用模拟框架......没有先学习一个好的教程。这些事情是复杂的。不要假设您可以预期如何做事。任何好的教程都会仔细地向你解释,仅仅创建一个模拟对象并不会神奇地将模拟对象推入其他对象......

标签: java junit mockito


【解决方案1】:

A 类实例化了它自己的B 实例,因此您的模拟实例永远不会被使用。相反,您可以重构 A 的构造函数以获取 B 对象的工厂或将在内部使用的 B 的实例。

要执行您最初描述的操作,您可以使用 PowerMock 完全替换该方法。

@PrepareForTest(B.class)
@RunWith(PowerMockRunner.class)
public class MyTests {
    @Test
    public void myTest {
        // Make B.methodB always return 20
        PowerMock.stub(PowerMock.method(B.class, "methodB")).toReturn(20);
    }
}

【讨论】:

    【解决方案2】:

    您可以在注入 bean 时使用 mock。在这里,您手动创建了一个 B 类实例。所以你的模拟在这里不会生效。

    【讨论】:

      猜你喜欢
      • 2014-05-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-12
      • 2018-07-17
      相关资源
      最近更新 更多