当我们无法将模拟对象传递给类的实例时,如何使用Mockito [英] How to use Mockito when we cannot pass a mock object to an instance of a class

查看:250
本文介绍了当我们无法将模拟对象传递给类的实例时,如何使用Mockito的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有这样的课程:

public class MyClass {

    Dao dao;

    public String myMethod(Dao d) {

        dao = d;

        String result = dao.query();

        return result;
    } 
}

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

I want to test it with mockito. So I create a mock object and I call the method to test in that way:

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

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

new MyClass().myMethod(mock);

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

But, suppose instead I have a class like that:

public class MyClass {

    Dao dao = new Dao();

    public String myMethod() {

        String result = dao.query();

        return result;
    } 
}

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

Now I cannot pass my mock as an argument, so how I gonna test my method? Can someone show an example?

推荐答案

从根本上说,你试图用一个替代实现替换一个私有字段,这意味着你这违反了封装。你唯一的另一个选择是重新构建类或方法,使其更好地设计用于测试。

Fundamentally, you're trying to replace a private field with an alternative implementation, which means you'd violate encapsulation. Your only other option is to restructure the class or method, to make it better-designed for testing.

评论中有很多简短的答案,所以我'我在这里汇总他们(并添加我自己的几个)作为社区Wiki。 如果您有任何其他选择,请随时在此处添加。

There are a lot of short answers in the comments, so I'm aggregating them here (and adding a couple of my own) as Community Wiki. If you have any alternatives, please feel free to add them here.


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

  • 创建依赖注入覆盖或静态方法接受DAO,并使公共实例方法委托给它。测试更灵活的方法。

  • Create a setter for the field in question, or relax the field's visibility.
  • Create a dependency-injecting override or static method that takes a DAO, and make the public instance method delegate to it. Test the more-flexible method instead.

public String myMethod() { return myMethod(dao); }
String myMethod(Dao dao) { /* real implementation here */ }


  • 添加构造函数重载或静态工厂方法,为了测试而替换私有字段。

  • 依赖注入。 ( Sotirios Delimanolis EJK

  • Add a constructor overload or static factory method that replaces private fields for the sake of testing.
  • Fully structure the class for dependency injection. (Sotirios Delimanolis, EJK)
  • 请注意,如果您将测试放在同一个测试中,其中一些可以是封装专用的Java包(可能在一个单独的源代码树中)。在所有情况下,良好的名称和文档都有助于明确您的意图。

    Note that some of these can be package-private for testing, if you put your tests in the same Java package (possibly in a separate source tree). In all cases, good names and documentation are helpful to make your intentions clear.

    • Use reflection to set private fields in the class. (kinbiko - see answer)
    • Use PowerMockito to replace the Dao constructor with a mock of your choice. (Dave Newton)

    这篇关于当我们无法将模拟对象传递给类的实例时,如何使用Mockito的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆