我在JUnit中有很多测试用例。所有这些都需要在@BeforeClass
静态方法中执行相同的代码。这是一个代码重复,我试图摆脱它。这样做的一种肮脏方式是继承。 JUnit中是否有其他机制可能会有所帮助?
PS。我写了这篇关于这个主题的博客文章:http://www.yegor256.com/2015/05/25/unit-test-scaffolding.html
答案 0 :(得分:38)
构建可重用代码(而不是从中继承)的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
答案 1 :(得分:4)
如果该方法是某种实用程序,则使用静态方法将其分离到另一个类,并在@BeforeClass中调用该方法。
我强调不使用继承只是因为它解决了你的问题,在这样做时使用它会在你的类层次结构中产生意义。
答案 2 :(得分:2)
您可以创建测试跑步者
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
}
}
答案 3 :(得分:1)
静态方法不是继承的,因此默认情况下继承不是一个选项。如果你的意思是你正在将方法移动到一个公共父类,那么这似乎是一个糟糕的选择,因为你只能在Java中获得一个父类。某种测试支持类似乎更合适。您也可能需要parameterized test。
答案 4 :(得分:1)
在这种情况下继承没有任何问题,它实际上是避免在每个子类中重复此代码的唯一方法。必须在JUnit中将@BeforeClass方法声明为静态这一事实是不幸的,但这不应该阻止你。扩展类,您可以自动为您运行初始化代码,而无需执行任何操作。
答案 5 :(得分:0)
如果每个类都需要一个完全的@BeforeClass
带注释的方法,那么继承就不会感觉 错误了我。如果这些初始化方法中的每一个都只是共享某些代码,那么您可以创建一个具有某些共享行为的TestUtil
类,并从每个@BeforeClass
方法调用此共享行为。
答案 6 :(得分:0)
我认为如果类具有“is-a”关系,则继承是合理的。
如果基类为MyBeforeClass
定义@BeforeClass
方法,而MyTestClass1
“is-a”MyBeforeClass
,MyTestClass1 extends MyBeforeClass
则可以。
答案 7 :(得分:0)
根据设置代码的性质,您可以将所有测试放在测试suite中,并在那里运行设置代码。这样做的缺点是你不能单独运行测试(因为测试取决于设置代码)。
答案 8 :(得分:-2)
它是测试代码,并不意味着重复使用。不要过度工程。不要应用您知道的所有设计模式。对于测试代码,规则是不同的。