带有 Spring 应用程序上下文的 JUnit 自定义运行器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5733959/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 04:26:59  来源:igfitidea点击:

JUnit custom runner with Spring application context

springjunitintegration-testingapplicationcontext

提问by DrewCo

I am fairly new to Spring and am working with a suite of JUnit 4.7 integration tests for a web application. I have a number of working test cases of the form:

我对 Spring 相当陌生,正在使用一套针对 Web 应用程序的 JUnit 4.7 集成测试。我有一些表单的工作测试用例:

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "/META-INF/spring/testContext.xml" })

public class myTest {
    @Test
    public void testCreate() {
            //execute tests
            ....
    }
}

My application has a number of external dependencies that I am testing, all of which have beans that are initialized through the loading of testContext.xml. Some of these external dependencies require custom code to initialize and tear down the necessary resources.

我的应用程序有许多我正在测试的外部依赖项,所有这些依赖项都有通过加载testContext.xml初始化的 bean 。其中一些外部依赖项需要自定义代码来初始化和拆除必要的资源。

Rather than duplicate this code in every test class that requires it, I would like to encapsulate it into a common location. My thought was to create a seperate context definition as well as a custom runner that extends SpringJUnit4ClassRunnerand contains the @ContextConfiguration annotation and related custom code, like so:

我不想在每个需要它的测试类中复制这段代码,而是想将它封装到一个公共位置。我的想法是创建一个单独的上下文定义以及一个扩展SpringJUnit4ClassRunner并包含 @ContextConfiguration 注释和相关自定义代码的自定义运行器,如下所示:

import org.junit.runners.model.InitializationError;
import org.junit.runners.model.Statement;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

//load the context applicable to this runner
@ContextConfiguration(locations = { "/META-INF/spring/testContext.xml" })

public class MyCustomRunner extends SpringJUnit4ClassRunner {

    public MyCustomRunner(Class<?> clazz) throws InitializationError {
        super(clazz);           
    }

    @Override
    protected Statement withBeforeClasses(Statement statement) {
        // custom initialization code for resources loaded by testContext.xml
                ...

        return super.withBeforeClasses(statement);
    }

    @Override
    protected Statement withAfterClasses(Statement statement) {
        // custom cleanup code for resources loaded by testContext.xml
                ....

        return super.withAfterClasses(statement);
    }

}

I could then have each test class specify its applicable runner with:

然后我可以让每个测试类指定其适用的运行器:

@RunWith(MyCustomRunner)

When I do this, my tests run and the proper withBeforeClassesand withAfterClassesmethods are executed. However, no applicationContext is provided back to the test class and all of my tests fail with:

当我这样做时,我的测试会运行并执行正确的withBeforeClasseswithAfterClasses方法。但是,没有将 applicationContext 提供回测试类,并且我的所有测试都失败了:

java.lang.IllegalArgumentException: Can not load an ApplicationContext with a NULL 'contextLoader'. Consider annotating your test class with @ContextConfiguration.

java.lang.IllegalArgumentException: 无法加载带有 NULL 'contextLoader' 的 ApplicationContext。考虑使用@ContextConfiguration 注释您的测试类。

The context only loads correctly if I specify the @ContextConfiguration annotation on each test class - ideally, I would like this annotation to live with the handler code for the resources it is responsible for loading. Which leads me to my question - is it possible to load Spring context information from a custom runner class?

只有当我在每个测试类上指定 @ContextConfiguration 注释时,上下文才会正确加载 - 理想情况下,我希望此注释与它负责加载的资源的处理程序代码一起存在。这引出了我的问题 - 是否可以从自定义运行器类加载 Spring 上下文信息?

回答by axtavt

You can create a base test class - @ContextConfigurationcan be inherited, as well as @Before, @After, and so on:

您可以创建一个基础测试类 -@ContextConfiguration可以继承,以及@Before@After,等等:

@ContextConfiguration(locations = { "/META-INF/spring/testContext.xml" }) 
public abstract class myBaseTest { 
    @Before
    public void init() {
        // custom initialization code for resources loaded by testContext.xml 
    }

    @After
    public void cleanup() {
        // custom cleanup code for resources loaded by testContext.xml
    }
}

@RunWith(SpringJUnit4ClassRunner.class)
public class myTest extends myBaseTest { ... }