Junit 我的@Rule如何与ExpectedException规则一起工作?

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

我创建了一个与@RunWith parameterized.class类似的@Rule,以便所有testcase都可以使用不同的参数重复测试(我不能直接使用parameterized.class,因为我的测试类已经有@RunWith用于其他用途)

但是,在测试以下方法时,@规则不起作用:

@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