我在JUnit中有很多测试用例。它们都需要使用相同的代码才能在其@BeforeClass
静态方法中执行。这是一个代码重复,我试图摆脱它。这样做的一个肮脏的方式是继承。 JUnit中是否有其他机制,可能有所帮助?如何避免JUnit测试用例中的继承?
PS。我写了这篇关于这个主题的博客文章:http://www.yegor256.com/2015/05/25/unit-test-scaffolding.html
我在JUnit中有很多测试用例。它们都需要使用相同的代码才能在其@BeforeClass
静态方法中执行。这是一个代码重复,我试图摆脱它。这样做的一个肮脏的方式是继承。 JUnit中是否有其他机制,可能有所帮助?如何避免JUnit测试用例中的继承?
PS。我写了这篇关于这个主题的博客文章:http://www.yegor256.com/2015/05/25/unit-test-scaffolding.html
JUnit组成可重用代码(而不是从中继承)的方式是规则。
见https://github.com/junit-team/junit/wiki/Rules
这是一个愚蠢的样品,但你会得到点。
import org.junit.rules.TestRule;
import org.junit.runners.model.Statement;
import org.junit.runner.Description;
public class MyTestRule implements TestRule {
@Override
public Statement apply(final Statement statement, Description description) {
return new Statement() {
public void evaluate() throws Throwable {
// Here is BEFORE_CODE
try {
statement.evaluate();
} finally {
// Here is AFTER_CODE
}
}
};
}
}
然后,您可以使用您的TestRule这样的:
import org.junit.Rule;
public class MyTest {
@Rule
public MyTestRule myRule = new MyTestRule();
}
BEFORE_CODE和AFTER_CODE然后将围绕每个测试方法执行。
如果你需要为每个班级只运行一次你的代码,用你的TestRule作为@ClassRule:
import org.junit.ClassRule;
public class MyTest {
@ClassRule
public static MyTestRule myRule = new MyTestRule();
}
现在,BEFORE_CODE
和AFTER_CODE
将围绕每个测试类的执行。
@Rule字段不是静态的,@ClassRule字段是。
@ClassRule也可以在套件中声明。
请注意,您可以在单个测试类中声明多个规则,这就是如何在测试套件,测试类和测试方法级别组成测试生命周期的方式。
规则是你在你的测试类中实例化的对象(静态或不静态)。如果需要,你可以添加构造器参数。
HTH
如果方法是某种实用工具,那么使用静态方法将其分离出来,并在@BeforeClass中调用该方法。
我强调这样一个事实,即不要仅仅因为它解决了你的问题而使用继承,而是在你的类层次结构中使用它。
如果每个类都需要有一个@BeforeClass
标注的方法是正是一样每隔,然后继承不觉得是我错了。如果这些初始化方法中的每一个都简单地共享代码,则可以使用某种共享行为创建一个TestUtil
类,并调用每个@BeforeClass
方法的此共享行为。
静态方法不会被继承,因此默认情况下继承不是一个选项。如果你的意思是你将方法移动到一个共同的父类,那么这看起来是一个糟糕的选择,因为你只能得到一个父Java。某种测试支持类似乎更合适。您也可能看到需要parameterized test。
我认为如果这些类有“is-a”的关系,继承是合理的。
如果基类是MyBeforeClass
定义@BeforeClass
方法,和MyTestClass1
“是一个” MyBeforeClass
,MyTestClass1 extends MyBeforeClass
是OK。
根据设置代码的性质,您可以将所有测试放在测试suite中,并让设置代码在那里运行。缺点是你不能单独运行测试(因为测试取决于设置代码)。
在这种情况下,继承没有任何问题,它实际上是避免在每个子类中重复此代码的唯一方法。 @BeforeClass方法必须在JUnit中声明为静态的事实是不幸的,但这不应该阻止你。扩展该类,并且您可以自动运行初始化代码,而无需执行任何操作。
不,它不是唯一的方法,看到其他答案,并且由于静态方法不被继承,它是否是一种方式是可疑的。你试过了吗? – EJP
您可以创建测试运行
public class MyTestRunner extends BlockJUnit4ClassRunner {
@Override
protected Object createTest() throws Exception {
Object test = super.createTest();
doStuff();
}
public void doStuff(){
//common code
}
}
@RunWith(MyTestRunner.class)
public class MyTest1{
@Test
public void test1(){
//test method
}
}
这是测试代码,这并不意味着对重型再利用。不要过度设计。不要应用你所知道的所有设计模式。对于测试代码,规则是不同的。
所有'@ BeforeClasses'完全相同还是只是共享一些代码? –
为什么继承是一种肮脏的方式? –
@lu,该方法是静态的,继承不会是最好的。 –