所以现在我正在使用JUnit 4,在@BeforeClass
方法中,我设置了重置用户模式或准备样本数据所需的一切。
现在,并不是我不喜欢这种方法,但我发现它非常令人沮丧,原因如下:
@BeforeClass
,因为@BeforeClass
适用于静态方法。这意味着如果我想保留@BeforeClass
逻辑,我必须复制测试。我不能使用@After和@Before
,因为这些将在每次测试后发生,这将是一个开销。
我想我可以重构这个单元测试,因为我会编写一个处理测试的抽象类,以及我想要尝试的每个组参数的子类,这样我就可以只编写一次测试代码。
我希望您可以使用以下起点建议更清晰的选项:使用@Parameterized
,每个参数组只需运行一次“数据库”方法。
编辑:
这是我没有BeforeClass
的班级的例子RunWith(LabelledParameterized.class)
public class TestCreateCampaign extends AbstractTestSubscriberCampaign {
public TestCreateCampaign(String label, String apiKey, String userKey,
int customerId) {
super(label, apiKey, userKey, customerId);
}
@Before
public void setUp() throws Exception {
super.setUp();
}
@After
public void tearDown() throws Exception {
super.tearDown();
}
@Parameters
public static Collection<Object[]> generatedData() {
return DataProvider.generatedCorrectSubscriberData();
}
@Test
public void testCreateEmailCampaignBothTriggered() {
// TEST
}
@Test
public void testCreateTextCampaignTriggered() {
// TEST
}
@Test
public void testCreateTextCampaignTest() {
// TEST
}
// Other Tests
}
答案 0 :(得分:0)
如何从参数化测试类的构造函数中调用setup方法?
编辑:
好的,我不知道任何自动执行此操作的内容,但我认为您可以编写Rule
代码来执行此操作。您可以从extend Rule
开始实现ExternalResource
。这是我认为它会做的。
ExternalResource
实例。@Test
注释的方法列表以获取计数。它会将迭代计数设置为0。before
方法中,它会增加迭代次数,如果在增量之后为1(或之前为0),它将在传递的before
上调用ExternalResource
方法。after
方法中,它会检查迭代次数是否等于测试次数,如果是,则调用传递的after
上的ExternalResource
方法。 您可能需要使用不同的回调类/接口和ExternalResource
,因为before
和after
方法是protected
。如果你真的想变得很酷,你可以在规则中定义自己的BeforeParameters
和AfterParameter
注释,它会在传递的实例中查找这些方法。
如果您开发此内容,请将其发布或提交给JUnit以便收录。
这是我提出的,不像我想的那样好:
@RunWith(Parameterized.class)
public class TestExample {
private interface BeforeAfter {
void before();
void after();
}
public static class Resource extends ExternalResource {
private final int count;
private final BeforeAfter ba;
private int iteration = 0;
Resource(Object instance, BeforeAfter ba) {
int localCount = 0;
for (Method method : instance.getClass().getMethods()) {
if (method.getAnnotation(Test.class) != null) {
localCount++;
}
}
this.count = localCount;
this.ba = ba;
}
@Override
protected void before() throws Throwable {
if (iteration == 0) {
ba.before();
}
iteration++;
}
@Override
protected void after() {
if (iteration == count) {
ba.after();
iteration = 0;
}
}
}
@Parameters
public static Iterable<Object[]> data() {
return Arrays.asList(new Object[][] { { 3, 0 }, { 4, 1 } });
}
@Rule
public static Resource resource = new Resource(new TestExample(0, 0), new BeforeAfter() {
@Override
public void before() {
System.out.println("setup");
}
@Override
public void after() {
System.out.println("cleanup");
}
});
private int fInput;
private int fExpected;
public TestExample(int input, int expected) {
// System.out.println("Constructor invoked" + fInput);
fInput = input;
fExpected = expected;
}
@Test
public void test1() {
System.out.println("test1 fInput=" + fInput);
}
@Test
public void test2() {
System.out.println("test2 fInput=" + fInput);
}
}
导致:
setup
test1 fInput=3
test2 fInput=3
cleanup
setup
test1 fInput=4
test2 fInput=4
cleanup
答案 1 :(得分:0)
这取决于您要如何设置类,但您可以使用ClassRule。这与TestRule完成相同的工作,但它为每个类运行一次,而不是每次测试。这可以与Parameterized和TestRule结合使用,例如:
@RunWith(Parameterized.class)
public class TestCreateCampaign {
@ClassRule
public static ExternalResource beforeAfterClass = new ExternalResource() {
@Override
protected void before() throws Throwable {
System.out.println("before each class");
}
@Override
protected void after() {
System.out.println("after each class");
}
};
@Rule
public ExternalResource beforeAfter = new ExternalResource() {
@Override
protected void before() throws Throwable {
System.out.println("before each test");
}
@Override
protected void after() {
System.out.println("after each test");
}
};
@Parameters(name = "{index}: fib({0})={1}")
public static Iterable<Object[]> data() {
return Arrays.asList(new Object[][] { { 3, 0 }, { 4, 1 } });
}
private int fInput;
private int fExpected;
public TestCreateCampaign(int input, int expected) {
fInput = input;
fExpected = expected;
}
@Test
public void test1() {
System.out.println("test1 fInput=" + fInput);
}
}
这会产生以下输出:
before each class
before each test
test1 3
after each test
before each test
test1 4
after each test
after each class
这似乎是你正在寻找的。为了减少重复量,你当然可以在一个单独的java类中定义beforeAfterClass和beforeAfter。
这些在JUnit 4.9 +。
中可用答案 2 :(得分:0)
有关每次测试运行仅初始化测试数据的方法,请参阅How to load DBUnit test data once per case with Spring Test。