如何设计单元测试类

时间:2018-02-28 12:24:32

标签: java unit-testing

我有一个类如下的Java类:

public class MyClass {

    /** Database Connection. */
    private dbCon;

    public MyClass() {
        dbCon = ...
    }

    public void doSomethingWith(MyData data) {
        data = convertData(data);
        dbCon.storeData(data);
    }

    private MyData convertData(MyData data) {
        // Some complex logic...
        return data;
    }
}

因为这个类的真正逻辑在于convertData()方法,所以我想为这个方法编写一个单元测试。 所以我读了这篇文章

How do I test a private function or a class that has private methods, fields or inner classes?

很多人都说测试私有方法的需要是设计气味。如何做得更好?

我看到两种方法:

  1. 使用公共API将convertData()方法解压缩到某个实用程序类中。但我认为这也是不好的做法,因为这样的实用程序类会违反单一责任原则,除非我用一两种方法创建了很多实用程序类。

  2. 编写第二个允许注入dbCon的构造函数,这允许我注入数据库连接的模拟版本并对公共doSomething()方法运行我的测试。这将是我的首选方法,但也有关于模拟的需求如何也是代码气味的讨论。

  3. 是否有关于此问题的最佳做法?

1 个答案:

答案 0 :(得分:3)

  

使用public api将convertData()方法解压缩到某个实用程序类中。但我认为这也是不好的做法,因为这样的实用程序类会违反单一责任原则,除非我用一两种方法创建了很多实用程序类。

你解释这是错误的。这正是SRP和SoC (关注点分离)建议的

public interface MyDataConverter {
    MyData convertData(MyData data);
}

public class MyDataConverterImplementation implements MyDataConverter {
    public MyData convertData(MyData data) {
        // Some complex logic...
        return data;
    }
}

convertData实现现在可以独立于MyClass

进行单独测试
  

编写第二个允许注入dbCon的构造函数,这允许我注入数据库连接的模拟版本并对公共doSomething()方法运行我的测试。这将是我的首选方法,但也有关于模拟的需求如何也是代码气味的讨论。

再次错了。研究显性依赖原则。

public class MyClass {
    private DbConnection dbCon;
    private MyDataConverter converter;

    public MyClass(DbConnection dbCon, MyDataConverter converter) {
        this.dbCon = dbCon;
        this.converter = converter;
    }

    public void doSomethingWith(MyData data) {
        data = converter.convertData(data);
        dbCon.storeData(data);
    }
}

MyClass现在对于执行其所需功能所需的内容更为诚实。

它也可以通过注入模拟依赖项进行单元测试。

相关问题