我有一个如下所示的 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?
很多人说需要测试私有(private)方法是一种设计味道。怎样才能做得更好?
我看到两种方法:
将
convertData()
方法提取到某个具有公共(public) API 的实用程序类中。但我认为这也是一种不好的做法,因为这样的实用程序类将违反单一责任原则,除非我创建大量的实用程序类,可能只有一两个方法。编写第二个构造函数,允许注入(inject)
dbCon
,它允许我注入(inject)数据库连接的模拟版本并针对公共(public)doSomething()
方法。这将是我首选的方法,但也有关于模拟需求如何也是代码味道的讨论。
关于这个问题有什么最佳实践吗?
最佳答案
Extract the convertData() method into some utility class with a public api. But I think this would be also bad practice since such utility classes will violate the single responsibility principle, unless I create a lot of utility classes with maybe only one or two methods.
您对此的解释是错误的。这正是 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
进行独立测试
Write a second constructor that allows injection of the dbCon, which allows me to inject a mocked version of the database connection and run my test against the public doSomething() method. This would be my preferred approach, but there are also discussions about how the need of mocking is also a code smell.
又错了。研究显式依赖原则。
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
现在更加诚实地了解执行其所需功能所需的内容。
它还可以通过注入(inject)模拟依赖项来单独进行单元测试。
关于java - 如何设计单元测试类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49029540/