对DI的部分模拟



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

这是一个简单的,做作的不现实的例子…假设File和FileFactory是接口

接口基构造函数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+click"createNewFile()"或"append"。在编写测试时,我可以使用/Mockito对该类进行部分模拟,并指示它返回"createFile(String)"的模拟文件,因此我仍然可以在测试期间注入依赖项。我看到这样做的好处。有什么我没发现的缺点吗?

我对java不太了解,但我知道c#中的DI,所以我想我能帮上一点忙。

首先,阅读这个stackoverflow问题。我问过要测试什么,为什么要制作mock。希望这个问题能给你一个做单元测试的总体思路。

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

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

  2. 最小依赖

    在您的例子中,您对FileFactory的依赖较少。这很好,因为它更容易设置测试。最小依赖的另一个好处是它的测试范围最小。

  3. 没有接口

    的附加功能

    在您的示例中,您有另一个函数public File createFile。我想知道它是否会被消费者使用(它是公共的)。恕我冒昧,最好将其设为私有,以确保单元测试不会调用额外的方法。

  4. 当测试类被改变时不会破坏测试类

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

相关内容

  • 没有找到相关文章

最新更新