在 JUnit 测试中是否有设置测试主题的规则

In a JUnit test is there a rule to set the subject of the test

我最近写了很多 JUnit 测试,看到了同样的样板模式。

public class MathOpTest {
   private MathOp a;

   @Before
   public void setUp(){
      a = new MathOp();
   }
   ...
}

是否有注释可以为我设置它,因为我总是需要编写一个 setUp 方法,而且它通常只有一个 class 我正在测试。

类似于:

public class MathOpTest {
   @TestSubject
   private MathOp a;
   ...
}

在我的记忆中,普通的 JUnit 中没有这样的东西。大多数人选择在 @Before 语句中或在测试内部初始化他们的测试对象。在它的辩护中,它明确了在测试 运行 之前建立的是什么,并且它总是重置测试对象的状态。

如果您使用的是 Mockito,您实际上确实可以通过声明 class 并使用 @InjectMocks 对其进行注释来实例化 class 并注入任何内容 [=12] =] class你之前有过。

您可以在声明时分配字段:

public class MathOpTest {
  private final MathOp mathOp = new MathOp();

  ...
}

这简单明了,所以我建议您尽可能在声明时 class 在测试 class 中分配字段 (当然在您提供的情况下).

如果您想了解更多,请继续阅读。

  • JUnit 将为每个测试方法创建一个唯一的测试实例 class,因此即使您的测试修改了 MathOp 的内部状态,只要您的测试以这种方式使用字段是安全的不要修改全局状态。
  • 对于 JUnit4 样式的测试(即不扩展 junit.framework.TestCase 的测试),JUnit 将在测试方法 运行 之前创建测试 class,并使其符合测试方法完成后的垃圾收集。

使用@Before方法进行更复杂的初始化。

通常我在以下情况下使用 @Before

  • 字段的初始化很复杂
  • 字段的初始化需要调用声明为抛出检查异常的代码
  • 您需要在应用 @Rule 之后进行初始化(例如,将模拟注入构造函数)

通常当 class 需要针对不同的用例以不同的方式构造时,您会在测试方法中创建被测对象。

例子

这里是一个使用@BeforeinitMocks()的例子:

public class MathOpTest {
  @Mock private Calculator mockCalculator;
  @Mock private Supplier<Double> mockPreviousResultSupplier;
  private MathOp mathOp;

  @Before
  public void createMathOp() {
    MockitoAnnotations.initMocks(this);
    mathOp = new MathOp(
        mockCalculator, mockPreviousResultSupplier);
  }

  ...
}

这是一个使用 @Rule 结果的 @Before 方法示例:

public class MyWriterTest {
  @Rule public final TemporaryFolder folder = new TemporaryFolder();
  private File output;
  private MyWriter writer;

  @Before
  public void createMyWriter() {
    output = folder.newFile();
    writer = new MyWriter(output);
  }

  ...
}

旁白: 我个人不建议使用 @InjectMocks 来创建您正在测试的 class。这对我来说太神奇了。拥有显式构造函数更清晰、更简单,我喜欢我的测试清晰简单:-)