如何在使用@RunWith和@ContextConfiguration注解的jUnit测试中访问Spring上下文?

68

我有下面这个测试类:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"/services-test-config.xml"})
public class MySericeTest {

  @Autowired
  MyService service;
...

}

是否有可能以编程方式访问services-test-config.xml,例如:

ApplicationContext ctx = somehowGetContext();

我相信即使使用基本的运行器JUnit4.class也是可能的,但是答案中忽略了这一点。我需要再多搜索一下谷歌。 - Sridhar Sarnobat
5个回答

94

这也可以正常工作:

@Autowired
ApplicationContext context;

确认,在Spring Integration 3.0.2中,最简洁的解决方案。 - Wrench
1
然而,这个解决方案仅在您将其用于托管bean中时才可行。通过实现ApplicationContextAware,即使在POJO中也能正常工作。 - Aditzu
在Spring 4.2上运行良好。 - cabaji99

62

由于测试也会像Spring bean一样实例化,因此您只需实现ApplicationContextAware接口:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"/services-test-config.xml"})
public class MySericeTest implements ApplicationContextAware
{

  @Autowired
  MyService service;
...
    @Override
    public void setApplicationContext(ApplicationContext context)
            throws BeansException
    {
        // Do something with the context here
    }
}

对于非 XML 需求,您也可以这样做:

@RunWith(SpringJUnit4ClassRunner.class)
/* must provide some "root" for the app-context, use unit-test file name to the context is empty */
@ContextConfiguration(classes = MyUnitTestClass.class)
public class MyUnitTestClass implements ApplicationContextAware {

2
目前为止,在Spring 3.0及以上版本中无法实现此功能。 - ALOToverflow

9
如果您的测试类扩展了Spring JUnit类(例如AbstractTransactionalJUnit4SpringContextTests或任何其他扩展AbstractSpringContextTests的类),则可以通过调用getContext()方法访问应用程序上下文。
请查看org.springframework.test包的javadocs

在我的junit测试中,使用AbstractTransactionalJUnit4SpringContextTests或AbstractSpringContextTests与简单地扩展ApplicationContextAware有什么区别?这个答案建议的两个抽象测试类提供了哪些好处? - Nelda.techspiress

2

通过使用SpringClassRuleSpringMethodRule规则,可以注入ApplicationContext类的实例。如果你想要使用其他非Spring运行器,这将非常方便。以下是一个示例:

@ContextConfiguration(classes = BeanConfiguration.class)
public static class SpringRuleUsage {

    @ClassRule
    public static final SpringClassRule springClassRule = new SpringClassRule();

    @Rule
    public final SpringMethodRule springMethodRule = new SpringMethodRule();

    @Autowired
    private ApplicationContext context;

    @Test
    public void shouldInjectContext() {
    }
}

0
创建了一个与这个问题相关的帖子,这对增加信心非常有帮助。
点击此链接获取更多详细信息。
@Test
void TestBeanLaunch()
{
    context.run(it -> {
        /*
         * I can use assertThat to assert on the context
         * and check if the @Bean configured is present
         * (and unique)
         */
        assertThat(it).hasSingleBean(PracticeApplication.class);
        assertThat(it).hasSingleBean(PracticeApplication.TestBean.class);
        assertThat(it.getBean("BeanTest")).isInstanceOf(PracticeApplication.TestBean.class);
    });
} 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接