当我们无法将模拟对象传递给类的实例时如何使用 Mockito

How to use Mockito when we cannot pass a mock object to an instance of a class(当我们无法将模拟对象传递给类的实例时如何使用 Mockito)
本文介绍了当我们无法将模拟对象传递给类的实例时如何使用 Mockito的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

限时送ChatGPT账号..

假设我有这样的课程:

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,或放宽该字段的可见性.

  • Create a setter for the field in question, or relax the field's visibility.

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

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 */ }

  • 添加构造函数重载或静态工厂方法来替换私有字段以进行测试.

  • Add a constructor overload or static factory method that replaces private fields for the sake of testing.

    完全构建依赖注入的类.(Sotirios Delimanolis, EJK)

    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.

    • 使用反射在类中设置私有字段.(kinbiko - 请参阅 answer)
    • 使用 PowerMockito 替换 Dao 构造函数与您选择的模拟.(戴夫·牛顿)
    • 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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

    本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!
  • 相关文档推荐

    Sending a keyboard event from java to any application (on-screen-keyboard)(将键盘事件从 java 发送到任何应用程序(屏幕键盘))
    How to make JComboBox selected item not changed when scrolling through its popuplist using keyboard(使用键盘滚动其弹出列表时如何使 JComboBox 所选项目不更改)
    Capturing keystrokes without focus(在没有焦点的情况下捕获击键)
    How can I position a layout right above the android on-screen keyboard?(如何将布局放置在 android 屏幕键盘的正上方?)
    How to check for key being held down on startup in Java(如何检查在Java中启动时按住的键)
    Android - Get keyboard key press(Android - 获取键盘按键)