【问题标题】:How to use Mockito when we cannot pass a mock object to an instance of a class当我们无法将模拟对象传递给类的实例时如何使用 Mockito
【发布时间】:2014-12-18 17:37:52
【问题描述】:

假设我有这样的课程:

public class MyClass {

    Dao dao;

    public String myMethod(Dao d) {

        dao = d;

        String result = dao.query();

        return result;
    } 
}

我想用 mockito 测试它。所以我创建了一个模拟对象并以这种方式调用该方法进行测试:

Dao mock = Mockito.mock(Dao.class);

Mockito.when(mock.myMethod()).thenReturn("ok");

new MyClass().myMethod(mock);

但是,假设我有一个这样的课程:

public class MyClass {

    Dao dao = new Dao();

    public String myMethod() {

        String result = dao.query();

        return result;
    } 
}

现在我不能将我的模拟作为参数传递,那么我将如何测试我的方法?有人可以举个例子吗?

【问题讨论】:

标签: java mockito


【解决方案1】:

从根本上说,您试图用替代实现替换私有字段,这意味着您违反了封装。您唯一的其他选择是重组类或方法,使其更适合测试。

cmets 中有很多简短的答案,所以我在这里汇总它们(并添加我自己的几个)作为社区 Wiki。 如果您有任何替代方案,请随时在此处添加。

重构类

  • 为相关字段创建一个 setter,或放宽该字段的可见性。

  • 创建一个采用 DAO 的依赖注入覆盖或静态方法,并将公共实例方法委托给它。改为测试更灵活的方法。

    public String myMethod() { return myMethod(dao); }
    String myMethod(Dao dao) { /* real implementation here */ }
    
  • 添加一个构造函数重载或静态工厂方法来替换私有字段以进行测试。

  • 完全构造dependency injection 的类。 (Sotirios Delimanolis, EJK)

请注意,如果您将测试放在同一个 Java 包中(可能在单独的源代码树中),其中一些可以是包私有的以进行测试。在任何情况下,良好的名称和文档都有助于明确您的意图。

违反封装

【讨论】:

    【解决方案2】:

    这个怎么样?

    public class MyClassTest {
    
        MyClass myClass = new MyClass();
        Dao dao = Mockito.mock(Dao.class);
    
        public void testMyMethod() {
    
            Field field = myClass.getClass().getDeclaredField("dao");
            field.setAccessible(true);
            field.set(myClass, dao);
            //Do the test...
        } 
    }
    

    编辑:如 cmets 中所述,这假定您不更改 dao 字段的名称。获取所有字段 Field[] fields = myClass.getClass().getDeclaredFields(); 并遍历它们,获取 Dao 类型的字段可能是个好主意。然后如上进行。这样您的测试就不再依赖于您的字段名称了。

    【讨论】:

    • 不错的方法,但有一个明显的限制,即如果字段名称发生变化,编译器将无法捕捉到这一点。然后,此测试将在运行时失败。
    猜你喜欢
    • 1970-01-01
    • 2015-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-09
    • 2015-05-24
    相关资源
    最近更新 更多