Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java DI的部分模拟?_Java_Unit Testing_Dependency Injection_Mocking_Mockito - Fatal编程技术网

Java DI的部分模拟?

Java DI的部分模拟?,java,unit-testing,dependency-injection,mocking,mockito,Java,Unit Testing,Dependency Injection,Mocking,Mockito,对于我的上一个Java项目,我对所有类进行了单元测试。每个类都有自己的接口和实现(即Person和PersonImpl)。类仅通过接口相互交互,我使用mock独立于其他类测试每个类。它最终真的很痛苦,因为它破坏了我的EclipseCtrl+click导航,因为每个方法调用都是在一个接口上调用的。每次我创建一个对象时都必须创建和传递依赖工厂,这也会使业务代码变得有点混乱,而该对象创建依赖关系是非常好的(除了测试之外)。我偶然发现了另一种依赖注入形式,它似乎可以解决这两个问题,我想知道是否有人能告诉

对于我的上一个Java项目,我对所有类进行了单元测试。每个类都有自己的接口和实现(即Person和PersonImpl)。类仅通过接口相互交互,我使用mock独立于其他类测试每个类。它最终真的很痛苦,因为它破坏了我的EclipseCtrl+click导航,因为每个方法调用都是在一个接口上调用的。每次我创建一个对象时都必须创建和传递依赖工厂,这也会使业务代码变得有点混乱,而该对象创建依赖关系是非常好的(除了测试之外)。我偶然发现了另一种依赖注入形式,它似乎可以解决这两个问题,我想知道是否有人能告诉我为什么这不是一个好主意

这里有一个简单的,人为的非现实的例子。。。假设文件和文件工厂是接口

接口基本构造函数DI

public class Logger {

    private File file;

    public Logger(FileFactory fileFactory, String fileName) {
        file = fileFactory.create(fileName);
        file.createNewFile();
    }

    public void debug(String message) {
        file.append("[debug] " + message);
    }

    public void error(String message) {
        file.append("[error] " + message);
    }
}
部分模拟依赖项注入

public class Logger {

    private File file;

    public Logger(String fileName) {
        file = createFile(fileName);
        file.createNewFile();
    }

    public void debug(String message) {
        file.append("[debug] " + message);
    }

    public void error(String message) {
        file.append("[error] " + message);
    }

    public File createFile(String fileName) {
        return new File(fileName);
    }
}

在第二个示例中,没有接口或工厂,类之间的关系被保留,因此我可以按住ctrl键并单击“createNewFile()”或“append”。在编写测试时,我可以使用Mockito对这个类进行部分模拟,并指示它为“createFile(String)”返回一个模拟文件,因此我仍然可以在测试期间注入依赖项。我认为这样做有好处。我不太喜欢java,但我知道C#中的DI,所以我想我可以帮点忙

首先,读一下这个。我问过要测试什么,为什么要进行模拟。希望这个问题能给出进行单元测试的一般思路

对我来说,在模拟对象中应该做什么:

  • 简单的

    简单的模拟对象可以使您的测试单元更容易检查。简单的模拟对象可以使它变得微不足道,并且不需要对模拟对象进行任何测试。一个简单的模拟对象将支持下面的第4点

  • 最小依赖性

    在您的情况下,您对FileFactory的依赖性较小。这很好,因为它更容易设置测试。具有最小依赖性的另一个好处是它具有最小的测试范围。它也将支持下面的第4点

  • 没有界面所需的附加功能

    在示例中,您有另一个函数
    public File createFile
    。我不知道消费者是否会使用它(它是公共的)。IMHO,最好将其私有化,以确保单元测试不会调用附加方法

  • 当测试类更改时,不会中断测试类

    模拟对象最重要的一点是,当测试类(使用者)发生更改时,模拟对象不会导致任何错误。因为您想对测试类进行单元测试,所以任何错误都应该只由测试类引起。当错误是由模拟对象引起时,将更难跟踪


  • 我对java不太感兴趣,但我知道C语言中的DI,所以我想我可以帮点忙

    首先,读一下这个。我问过要测试什么,为什么要进行模拟。希望这个问题能给出进行单元测试的一般思路

    对我来说,在模拟对象中应该做什么:

  • 简单的

    简单的模拟对象可以使您的测试单元更容易检查。简单的模拟对象可以使它变得微不足道,并且不需要对模拟对象进行任何测试。一个简单的模拟对象将支持下面的第4点

  • 最小依赖性

    在您的情况下,您对FileFactory的依赖性较小。这很好,因为它更容易设置测试。具有最小依赖性的另一个好处是它具有最小的测试范围。它也将支持下面的第4点

  • 没有界面所需的附加功能

    在示例中,您有另一个函数
    public File createFile
    。我不知道消费者是否会使用它(它是公共的)。IMHO,最好将其私有化,以确保单元测试不会调用附加方法

  • 当测试类更改时,不会中断测试类

    模拟对象最重要的一点是,当测试类(使用者)发生更改时,模拟对象不会导致任何错误。因为您想对测试类进行单元测试,所以任何错误都应该只由测试类引起。当错误是由模拟对象引起时,将更难跟踪