我这里有一个有趣的 JUnit 问题(JUnit 4.12)。我有一个只有静态方法的基类。由于它们的使用方式,它们必须是静态的。我从基类继承了其他类。所以,如果基类是Base
, 我们有ChildA
and ChildB
.
大多数方法都包含在基类中,但它必须知道它实际上是哪个子类(仅作为基类调用方法是无效的)。这是通过基类中的静态数据成员完成的:
public class Base {
protected static ChildType myType = ChildType.Invalid;
...
}
每个子进程都通过静态初始化器设置数据成员,因此:
static {
myType = ChildType.ChildA;
}
然后,当调用方法时,基类知道它是什么类型并加载适当的配置(类型实际上是配置名称)。
运行应用程序时,这一切都可以完美运行。在调试器中单步执行并通过日志消息,我可以看到设置了适当的类型,并且方法根据子类型加载了适当的配置。
使用 JUnit 时会出现问题。我们有一些 JUnit 测试来测试每个基类方法。由于仅调用基类上的方法是无效的,因此我们调用子类上的方法,因此:
bool result = ChildA.methodTwo();
这“总是失败”。为什么?静态初始化器永远不会被调用。当代码作为应用程序运行时,它会被调用,每个人都很高兴。当我将其作为 JUnit 测试运行时,静态初始化程序将被跳过,并且方法具有无效数据。 JUnit 正在做什么跳过静态初始化器?有办法解决吗?
Details
实际上,我们并没有调用我上面发布的方法。我只是想让这个例子尽可能清楚。实际上,我们有一个用 Jersey 框架编写的 Web 服务。调用的方法是 REST 端点之一。
@POST
@Produces(MediaType.TEXT_PLAIN)
public String methodPost() {
...
return new String( itWorked ? "success" : "fail" );
}
我们这样称呼它(很抱歉语法丑陋,这只是它的工作方式):
@Test
public void testThePost() throws Exception {
javax.ws.rs.core.Response response = target("restapi/").request().post(Entity.entity(null, MediaType.TEXT_PLAIN));
assertEquals( 200, response.getStatus() );
}
所有 GET 测试都有效,并且对所有测试都调用静态初始化程序。只是这个 POST 失败,并且仅在运行 JUnit 测试时失败。