【发布时间】:2011-07-17 14:15:18
【问题描述】:
为接口编写 junit 测试以便它们可用于具体实现类的最佳方法是什么?
例如你有这个接口和实现类:
public interface MyInterface {
/** Return the given value. */
public boolean myMethod(boolean retVal);
}
public class MyClass1 implements MyInterface {
public boolean myMethod(boolean retVal) {
return retVal;
}
}
public class MyClass2 implements MyInterface {
public boolean myMethod(boolean retVal) {
return retVal;
}
}
您将如何针对接口编写测试,以便将其用于类?
可能性一:
public abstract class MyInterfaceTest {
public abstract MyInterface createInstance();
@Test
public final void testMyMethod_True() {
MyInterface instance = createInstance();
assertTrue(instance.myMethod(true));
}
@Test
public final void testMyMethod_False() {
MyInterface instance = createInstance();
assertFalse(instance.myMethod(false));
}
}
public class MyClass1Test extends MyInterfaceTest {
public MyInterface createInstance() {
return new MyClass1();
}
}
public class MyClass2Test extends MyInterfaceTest {
public MyInterface createInstance() {
return new MyClass2();
}
}
专业:
- 只需要实现一种方法
缺点:
- 被测类的依赖项和模拟对象对于所有测试都必须相同
可能性2:
public abstract class MyInterfaceTest
public void testMyMethod_True(MyInterface instance) {
assertTrue(instance.myMethod(true));
}
public void testMyMethod_False(MyInterface instance) {
assertFalse(instance.myMethod(false));
}
}
public class MyClass1Test extends MyInterfaceTest {
@Test
public void testMyMethod_True() {
MyClass1 instance = new MyClass1();
super.testMyMethod_True(instance);
}
@Test
public void testMyMethod_False() {
MyClass1 instance = new MyClass1();
super.testMyMethod_False(instance);
}
}
public class MyClass2Test extends MyInterfaceTest {
@Test
public void testMyMethod_True() {
MyClass1 instance = new MyClass2();
super.testMyMethod_True(instance);
}
@Test
public void testMyMethod_False() {
MyClass1 instance = new MyClass2();
super.testMyMethod_False(instance);
}
}
专业:
- 每个测试的精细粒度,包括依赖项和模拟对象
缺点:
- 每个实现测试类都需要编写额外的测试方法
您更喜欢哪种可能性或您使用什么其他方式?
【问题讨论】:
-
当具体类在不同的包、组件或开发团队中时,可能性 1 是不够的。
-
@AndyThomas:你为什么这么说?我在不同的包和 Maven 项目中将可能性 1 与具体类(用于实现和测试)一起使用。
-
@TrevorRobinson - 回想那个三年前的评论,我现在能想到的就是你无法控制的类可能有多个构造函数,但可能性 1 在一个仅使用其中之一创建的对象。
-
使用选项1,您可以在每个具体类中拥有单独的@Before 方法。您还可以根据需要在具体课程中进行一次性测试。
标签: java unit-testing testing interface junit