Junit 我的@Rule如何与ExpectedException规则一起工作?
我创建了一个与@RunWith parameterized.class类似的@Rule,以便所有testcase都可以使用不同的参数重复测试(我不能直接使用parameterized.class,因为我的测试类已经有@RunWith用于其他用途) 但是,在测试以下方法时,@规则不起作用:Junit 我的@Rule如何与ExpectedException规则一起工作?,junit,rule,Junit,Rule,我创建了一个与@RunWith parameterized.class类似的@Rule,以便所有testcase都可以使用不同的参数重复测试(我不能直接使用parameterized.class,因为我的测试类已经有@RunWith用于其他用途) 但是,在测试以下方法时,@规则不起作用: @Test public void fooTest() { /*exception is an ExceptedException initialized somewhere else as: *@Rule
@Test
public void fooTest() {
/*exception is an ExceptedException initialized somewhere else as:
*@Rule public ExpectedException exception = ExpectedException.none();
*/
exception.expect(A);
exception.expectMessage(B);
someTestWhichThrowExceptionOfB();
}
事实上,如果我将参数硬编码为一个值,测试通过,因为它确实抛出了B异常。
但是如果我设置参数=MyParameterRule.value(),测试也会抛出一个B异常,但随后失败,并说它失败是因为B异常
我猜在第二种情况下,如果我使用MyParameterRule,那么异常不起作用?那为什么呢?如何使它仍然工作?如果您可以依赖JUnit 4.12,则可以将参数化的
与@UseParametersRunnerFactory一起使用(有关详细信息,请参阅)
至于您的参数化规则不起作用的原因,这里有一个(有点长的)解释
JUnit有一个内部假设,即为每个测试方法创建一个测试类的新实例。JUnit这样做是为了使存储在一个测试方法运行的测试实例中的状态不会影响下一个测试方法运行
ExpectedException
规则具有相同的期望。调用expect
时,它会更改在该字段初始化时创建的ExpectedException
字段的状态。它将其修改为“期望”抛出异常
当您的规则尝试两次运行同一方法(使用不同的参数)违反此假设时。第一次调用调用expect
的方法时,它会工作,但再次调用时,它可能不会工作,因为您正在使用先前修改的ExpectedException
规则
当JUnit为JUnit4样式的测试运行测试方法时,它会执行以下操作:
创建测试类的实例
创建将运行测试方法的语句
如果方法的@Test
注释使用expected
属性,请使用另一个处理预期异常的语句包装语句
如果方法的@Test
注释使用timeout
属性,请使用另一个处理超时的语句包装语句
将该语句
与其他语句包装在一起,这些语句将调用在@之前
和@之后注释的方法
将该语句
与调用规则的其他语句包装在一起
有关更多详细信息,请参阅
因此,传递给您的规则的语句
包装了一个已经构造好的类(它必须这样做,因此您的规则的apply()
方法被调用)
不幸的是,这意味着不应使用规则
多次运行测试方法,因为测试(或其规则)的状态可能是在上次运行方法时设置的
如果您不能依赖JUnit 4.12,您可以通过使用规则链
规则来确保用于多次运行测试的自定义规则“围绕”其他规则运行。如果您可以依赖JUnit 4.12,您可以将参数化的与@UseParametersRunnerFactory
一起使用(有关详细信息,请参阅)
至于您的参数化规则不起作用的原因,这里有一个(有点长的)解释
JUnit有一个内部假设,即为每个测试方法创建一个测试类的新实例。JUnit这样做是为了使存储在一个测试方法运行的测试实例中的状态不会影响下一个测试方法运行
ExpectedException
规则具有相同的期望。调用expect
时,它会更改在该字段初始化时创建的ExpectedException
字段的状态。它将其修改为“期望”抛出异常
当您的规则尝试两次运行同一方法(使用不同的参数)违反此假设时。第一次调用调用expect
的方法时,它会工作,但再次调用时,它可能不会工作,因为您正在使用先前修改的ExpectedException
规则
当JUnit为JUnit4样式的测试运行测试方法时,它会执行以下操作:
创建测试类的实例
创建将运行测试方法的语句
如果方法的@Test
注释使用expected
属性,请使用另一个处理预期异常的语句包装语句
如果方法的@Test
注释使用timeout
属性,请使用另一个处理超时的语句包装语句
将该语句
与其他语句包装在一起,这些语句将调用在@之前
和@之后注释的方法
将该语句
与调用规则的其他语句包装在一起
有关更多详细信息,请参阅
因此,传递给您的规则的语句
包装了一个已经构造好的类(它必须这样做,因此您的规则的apply()
方法被调用)
不幸的是,这意味着不应使用规则
多次运行测试方法,因为测试(或其规则)的状态可能是在上次运行方法时设置的
如果您不能依赖JUnit 4.12,您可以通过使用规则链规则来解决这个问题,以确保用于多次运行测试的自定义规则“围绕”其他规则运行。如果您可以依赖JUnit 4.12,您可以使用参数化的和@UseParametersRunnerFact