在 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 需要针对不同的用例以不同的方式构造时,您会在测试方法中创建被测对象。
例子
这里是一个使用@Before
和initMocks()
的例子:
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。这对我来说太神奇了。拥有显式构造函数更清晰、更简单,我喜欢我的测试清晰简单:-)
我最近写了很多 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 需要针对不同的用例以不同的方式构造时,您会在测试方法中创建被测对象。
例子
这里是一个使用@Before
和initMocks()
的例子:
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。这对我来说太神奇了。拥有显式构造函数更清晰、更简单,我喜欢我的测试清晰简单:-)