静态初始值设定项在JUnit测试期间未运行 [英] Static initializer doesn't run during JUnit tests

查看:81
本文介绍了静态初始值设定项在JUnit测试期间未运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这里有一个有趣的JUnit问题(JUnit 4.12).我有一个仅具有静态方法的基类.由于它们的使用方式,它们必须是静态的.我从基类继承其他类.因此,如果基类为Base,则有ChildAChildB.

I have an interesting JUnit problem here (JUnit 4.12). I have a base class that only has static methods. They have to be static, because of the way they're used. I inherit other classes from the base class. So, if the base class is Base, we have ChildA and ChildB.

大多数方法都包含在基类中,但是它必须知道它实际上是哪个子类(仅在基类无效时才调用这些方法).这是通过基类中的静态数据成员完成的:

Most of the methods are contained in the base class, but it has to know which child it actually is (just calling the methods as the base class is invalid). This is done via a static data member in the base class:

public class Base {

    protected static ChildType myType = ChildType.Invalid;
    ...
}    

每个子级都通过静态初始化程序设置数据成员,因此:

Each child sets the data member via a static initializer, thus:

static {
    myType = ChildType.ChildA;
}

然后,在调用方法时,基类会知道它是什么类型并加载适当的配置(该类型实际上是配置名称).

Then when the methods are called, the base class knows what type it is and loads the appropriate configurations (the type is actually a configuration name).

在运行应用程序时,这一切都可以完美运行.在调试器中逐步执行它,并通过日志消息,可以看到已设置了适当的类型,并且该方法根据子类型加载了适当的配置.

This all works perfectly when running the application. Stepping through it in the debugger and through log messages, I can see the appropriate types are set and the methods load the appropriate configurations based on the child type.

使用JUnit时出现问题.我们有一些JUnit测试来测试每个基类方法.由于仅在基类上调用方法无效,因此我们在子类上调用方法,因此:

The problem arises when using JUnit. We have some JUnit tests to test each of the base class methods. Since calling the methods on just the base class is invalid, we call the methods on the child classes, thus:

bool result = ChildA.methodTwo();

这总是失败".为什么?静态初始化器永远不会被调用.当将代码作为应用程序运行时,它将被调用,并且每个人都很高兴.当我将其作为JUnit测试运行时,将跳过静态初始值设定项,并且这些方法具有无效的数据. JUnit在做什么,从而跳过了静态初始化程序?有办法解决吗?

This ''always fails''. Why? The static initializer never gets called. When running the code as an application, it gets called, and everyone is happy. When I run it as a JUnit test, the static initializer is skipped and the methods have invalid data. What is JUnit doing that skips the static initializer? Is there a way around it?

详细信息

实际上,我们没有调用我上面发布的方法.我只是想让例子尽可能清楚.实际上,我们有一个使用Jersey框架编写的Web服务.调用的方法是REST端点之一.

In reality, we're not calling the method as I posted above. I just wanted the example to be as clear as possible. In reality, we have a Web Service written with the Jersey framework. The method called is one of the REST endpoints.

@POST
@Produces(MediaType.TEXT_PLAIN)
public String methodPost() {
    ...
    return new String( itWorked ? "success" : "fail" );
}

我们这样称呼它(对不起丑陋的语法,这只是它的工作方式):

And we call it like this (sorry about the ugly syntax, it's just the way it works):

@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测试时才会发生.

All the GET tests work, and the static initializer is called on all of them. It's just this POST that fails, and only when running the JUnit test.

推荐答案

我决定尝试@Arkdiy提出的建议,并在子类中使用传递方法.

I decided to try what @Arkdiy suggested and have pass-through methods in the child classes.

让我重申一下:正如我所拥有的那样,代码在作为应用程序运行时可以完美地工作.只有通过JUnit运行时,它才会失败.

所以现在我有类似下面的内容:

So now I have something similar to the below:

public class BaseClass {

    protected static ChildType myType = ChildType.Invalid;

    ...

    public static boolean methodTwoBase() {
        ...
    }
}

public class ChildA extends BaseClass {

    public static boolean methodOne() {
        ...
    }

    public static boolean methodTwo() {

        myType = ChildType.ChildA;
        return methodTwoBase();
    }
}

public class ChildB extends BaseClass {

    public static boolean methodOne() {
        ...
    }

    public static boolean methodTwo() {

        myType = ChildType.ChildB;
        return methodTwoBase();
    }
}

由于我无法覆盖静态方法,因此基类中方法的版本具有不同的签名(methodTwoBase()而不是methodTwo).我将其作为常规应用程序并在JUnit中进行了尝试,并且可以双向工作.

Since I can't override static methods, the version of the method in the base class has a different signature (methodTwoBase() instead of methodTwo). I tried it as a regular application and in JUnit and it works both ways.

有一个有趣的问题,我要怪JUnit.感谢您的所有投入!

Kind of an interesting problem, and I blame JUnit. Thanks for all the input!

这篇关于静态初始值设定项在JUnit测试期间未运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆