在单元测试中使用模拟实现修补Java类

时间:2012-09-30 20:54:58

标签: java unit-testing mocking

我有一个A类,它在内部实例化B类中的对象。第二类有很多外部副作用,例如:它使用网络连接。

public class A {
  private B b;
  public A() {
    b = new B(); // 3rd party class that calls out externally (e.g. to a db)
  }
}

我想通过提供类B的模拟实现来对A类进行单元测试。我可以通过编写自己的类或使用类似Mockito和其他框架的东西轻松创建B的模拟版本,但是如何注入这个模拟实现到A类的代码?

我想我可以在A类的构造函数中要求一个B类实例,但这看起来很难看。没有人真正需要知道A级如何做它的业务。

Python有一个“模拟”库,允许您在测试期间在运行时“修补”函数。 Java有类似的东西吗?

3 个答案:

答案 0 :(得分:3)

在这种情况下,我通常有一个第二个包(默认)范围构造函数,允许您传递模拟以进行测试。

public class A {
  private B b;

  /*
  *  Used by clients
  */
  public A() {
    this(new B());
  }

  /*
  * Used by unit test
  * 
  * @param b A mock implementation of B
  */
  A(B b) {
    this.b = b;
  }
}

答案 1 :(得分:0)

查看Mockito.最终,根据您的设计,您需要使用反射将B的模拟实例转换为A.

答案 2 :(得分:0)

使用JMockit模拟API解决这个问题很简单:

public class ATest
{
    @Test
    public void myTest(@Mocked B mockB)
    {
        // Record expectations on "mockB", if needed.

        new A().doSomethingUsingB();

        // Verify expectations on "mockB", if applicable.
    }
}