繁体   English   中英

如何在JUnit测试用例中避免继承?

[英]How to avoid inheritance in JUnit test cases?

我在JUnit中有很多测试用例。 所有这些都需要在@BeforeClass静态方法中执行相同的代码。 这是一个代码重复,我试图摆脱它。 这样做的一种肮脏方式是继承。 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_CODEAFTER_CODE将在每个测试类周围执行。

@Rule字段不是静态的, @ ClassRule字段是。

@ClassRule也可以在套件中声明。

请注意,您可以在单个测试类中声明多个规则,这就是在测试套件,测试类和测试方法级别组成测试生命周期的方式。

规则是您在测试类中实例化的对象(静态或非静态)。 如果需要,您可以添加构造函数参数。

HTH

如果该方法是某种实用程序,则使用静态方法将其分离到不同的类,并在@BeforeClass中调用该方法。

我强调的是,不要仅仅因为它解决了你的问题而使用继承,在这样做时使用它会在你的类层次结构中产生意义。

您可以创建测试运行器

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
    }
}

静态方法不是继承的,因此默认情况下继承不是一个选项。 如果你的意思是你正在将方法移动到一个公共父类,那么这似乎是一个糟糕的选择,因为你只能在Java中获得一个父类。 某种测试支持类似乎更合适。 您也可能需要进行参数化测试

在这种情况下,继承绝对没有错,它实际上是避免在每个子类中重复此代码的唯一方法。 必须在JUnit中将@BeforeClass方法声明为静态这一事实是不幸的,但这不应该阻止你。 扩展类,您可以自动为您运行初始化代码,而无需执行任何操作。

如果每个类都需要有一个@BeforeClass标注的方法是完全一样的,因为每个其他,然后继承不觉得我错了。 如果这些初始化方法中的每一个只是共享一些代码,那么可以使TestUtil类具有一些共享行为,并从每个@BeforeClass方法调用此共享行为。

我认为如果类具有“is-a”关系,则继承是合理的。

如果基类是定义@BeforeClass方法的MyBeforeClass ,而MyTestClass1 “是MyBeforeClassMyBeforeClass ,则MyTestClass1 extends MyBeforeClass就可以了。

根据设置代码的性质,您可以将所有测试放在测试套件中 ,并在那里运行设置代码。 这样做的缺点是您无法单独运行测试(因为测试取决于设置代码)。

它是测试代码 ,并不意味着重复使用。 不要过度工程。 不要应用您知道的所有设计模式。 对于测试代码 ,规则是不同的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM