使用jUnit 4,我可以参数化@BeforeClass吗?

时间:2012-06-22 20:47:43

标签: junit integration-testing junit4 parameterized

我正在使用jUnit来管理访问数据库的应用程序的集成测试。因为设置测试数据是一项耗时的操作,所以我一直在@BeforeClass方法中这样做,每个测试类只执行一次(而不是运行的@Before方法)每种测试方法一次。)

现在我想尝试一些不同的排列来配置数据层,在每个不同的配置上运行我的所有测试。这似乎是Parameterized测试运行器的自然使用。问题是,Parameterized为类构造函数提供参数,@BeforeClass方法是抽象的,并在类构造函数之前调用。

几个问题,

Parameterized是否为每个参数排列调用@BeforeClass方法,还是只调用一次?

如果重复调用@BeforeClass方法,是否有某种方法可以从内部访问参数值?

如果没有这些,人们认为什么是解决这个问题的最佳替代方法?

5 个答案:

答案 0 :(得分:3)

我认为你需要一个自定义测试运行器。我遇到了同样的问题(需要使用多个昂贵的配置运行相同的测试)。您需要一种方法来参数化设置,可能使用类似于参数化运行器使用的@Parameter注释,但是使用静态成员字段而不是实例字段。自定义运行器必须使用@Parameter注释查找所有静态成员字段,然后每个静态@Parameter字段运行一次测试类(可能使用基本的BlockJunit4ClassRunner)。 @Parameter字段应该是@ClassRule。

Andy on Software在开发自定义测试运行器方面做得很好,他在这些博文herehere中非常清楚地解释了这一点。

答案 1 :(得分:1)

@BeforeClass仅在您的示例中调用一次。考虑到这个名字,这在课前是有道理的!

如果你的测试需要不同的数据,我可以想到两个选择:

  1. 在@Before中设置该数据,因此它是特定于测试的
  2. 将要使用相同数据运行的测试分组到单独的测试类中,并为每个测试类使用@BeforeClass。

答案 2 :(得分:0)

您可以在测试类的构造函数中调用此初始化逻辑。跟踪静态变量中使用的最后一个参数。更改时,请为新参数设置类。

我想不出AfterClass的等价物。

答案 3 :(得分:0)

这是一个老问题,但我只需解决一个可能类似的问题。我现在使用下面的解决方案,这实际上是使用通用抽象基类的TREE(更新)答案的实现,以便在需要此机制时避免重复。

具体测试将提供一个@Parameters方法,该方法返回包含Supplier< T>每。然后,根据具体测试方法所需的实际输入,这些供应商只执行一次。

@RunWith(Parameterized.class)
public class AbstractBufferedInputTest<T> {

private static Object INPUT_BUFFER;

private static Object PROVIDER_OF_BUFFERED_INPUT;

private T currentInput;

@SuppressWarnings("unchecked")
public AbstractBufferedInputTest(Supplier<T> inputSuppler) {
    if (PROVIDER_OF_BUFFERED_INPUT != inputSuppler) {
        INPUT_BUFFER = inputSuppler.get();
        PROVIDER_OF_BUFFERED_INPUT = inputSuppler;
    }
    currentInput = (T) INPUT_BUFFER;
}

/**
 * 
 * @return the input to be used by test methods
 */
public T getCurrentInput() {
    return currentInput;
}

}

答案 4 :(得分:-1)

您可以在@Before方法中进行初始化,写入实例变量但测试为null。

@RunWith(value = Parameterized.class)
public class BigThingTests {
  private BigThing bigThing;

  @Before
  public void createBitThing() {
    if (bigThing == null) {
      bigThing = new BigThing();
    }
  }

...
}

为每组参数创建BigThingTests的新实例,并为每个新实例将bigThing设置为null。 Parameterized运行器是单线程的,因此您不必担心多次初始化。