AbstractJUnit4SpringContextTests

AbstractJUnit4SpringContextTests

本文介绍了在春季测试中请求范围豆的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在我的应用中使用请求范围的bean。我使用JUnit4进行测试。如果我尝试在这样的测试中创建一个:

I would like to make use of request scoped beans in my app. I use JUnit4 for testing. If I try to create one in a test like this:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:spring/TestScopedBeans-context.xml" })
public class TestScopedBeans {
    protected final static Logger logger = Logger
            .getLogger(TestScopedBeans.class);

    @Resource
    private Object tObj;

    @Test
    public void testBean() {
        logger.debug(tObj);
    }

    @Test
    public void testBean2() {
        logger.debug(tObj);
    }

使用以下bean定义:

With the following bean definition:

 <?xml version="1.0" encoding="UTF-8"?>
 <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  <bean class="java.lang.Object" id="tObj" scope="request" />
 </beans>

我得到:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'gov.nasa.arc.cx.sor.query.TestScopedBeans': Injection of resource fields failed; nested exception is java.lang.IllegalStateException: No Scope registered for scope 'request'
<...SNIP...>
Caused by: java.lang.IllegalStateException: No Scope registered for scope 'request'

所以我发现这个博客看起来很有帮助:

So I found this blog that seemed helpful:http://www.javathinking.com/2009/06/no-scope-registered-for-scope-request_5.html

但是我注意到他使用似乎在Spring 3.0中被弃用了。
我现在使用的是Spring 2.5,但是认为切换这个方法以使用AbstractJUnit4SpringContextTests
作为文档建议应该不会太难(确定文档链接到3.8版但我正在使用4.4)。所以我改变
测试来扩展AbstractJUnit4SpringContextTests ...同样的消息。同样的问题。现在我想要
覆盖的prepareTestInstance()方法没有定义。好吧,也许我会把那些registerScope调用放在其他地方......所以我读了更多关于并认为这会更好,因为我不想继承spring包结构。所以
我将我的测试更改为:

But I noticed he uses AbstractDependencyInjectionSpringContextTests which seems to be deprecated in Spring 3.0.I use Spring 2.5 at this time, but thought it shouldn't be too hard to switch this method to use AbstractJUnit4SpringContextTestsas the docs suggest (ok the docs link to the 3.8 version but I'm using 4.4). So I change thetest to extend AbstractJUnit4SpringContextTests... same message. Same problem. And now the prepareTestInstance() method I wantto override is not defined. OK, maybe I'll put those registerScope calls somewhere else... So I read more about TestExecutionListeners and think that would be better since I don't want to have to inherit the spring package structure. SoI changed my Test to:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:spring/TestScopedBeans-context.xml" })
@TestExecutionListeners({})
public class TestScopedBeans {

期待我必须创建一个自定义监听器,但是当我运行它时。有用!很好,但为什么呢?我没有看到任何股票监听者
在哪里注册请求范围或会话范围,为什么会这样?没有什么可说的我想要的,这可能不是Spring MVC代码的测试...

expecting I would have to create a custom listener but I when I ran it. It works! Great, but why? I don't see where any of the stock listenersare registering request scope or session scope, and why would they? there's nothing to say I want that yet, this might not be a Test for Spring MVC code...

推荐答案

测试通过因为它没有做任何事情:))

The test passes because it isn't doing anything :)

当你省略 @TestExecutionListeners 注释时,Spring会注册3个默认监听器,包括一个名为 DependencyInjectionTestExecutionListener 。这是负责扫描您的测试类寻找要注入的东西的监听器,包括 @Resource 注释。这个监听器试图注入 tObj ,并因为未定义范围而失败。

When you omit the @TestExecutionListeners annotation, Spring registers 3 default listeners, including one called DependencyInjectionTestExecutionListener. This is the listener responsible for scanning your test class looking for things to inject, including @Resource annotations. This listener tried to inject tObj, and fails, because of the undefined scope.

当你声明<$ c时$ c> @TestExecutionListeners({}),您禁止注册 DependencyInjectionTestExecutionListener ,因此测试永远不会得到完全注入了tObj ,并且因为你的测试没有检查是否存在 tObj ,它会通过。

When you declare @TestExecutionListeners({}), you suppress the registration of the DependencyInjectionTestExecutionListener, and so the test never gets tObj injected at all, and because your test is not checking for the existence of tObj, it passes.

修改你的测试,这样做就会失败:

Modify your test so that it does this, and it will fail:

@Test
public void testBean() {
    assertNotNull("tObj is null", tObj);
}

所以你的空 @TestExecutionListeners ,测试通过,因为没有任何反应

So with your empty @TestExecutionListeners, the test passes because nothing happens.

现在,问你原来的问题。如果您想尝试使用测试上下文注册请求范围,那么请查看 WebApplicationContextUtils.registerWebApplicationScopes()的源代码,您将找到以下行:

Now, on to your original problem. If you want to try registering the request scope with your test context, then have a look at the source code for WebApplicationContextUtils.registerWebApplicationScopes(), you'll find the line:

beanFactory.registerScope(WebApplicationContext.SCOPE_REQUEST, new RequestScope());

你可以尝试一下,看看你怎么做,但可能有奇怪的副作用,因为你不是真的打算在测试中这样做。

You could try that, and see how you go, but there might be odd side-effects, because you're not really meant to do this in a test.

相反,我建议你重新测试你的测试,这样你就不需要了请求范围豆。这应该不难,如果你编写自包含的测试, @Test 的生命周期不应该长于请求范围的bean的生命周期。记住,没有必要测试作用域机制,它是Spring的一部分,你可以认为它有效。

Instead, I would recommend rephrasing your test so that you don't need request scoped beans. This shouldn't be difficult, the lifecycle of the @Test shouldn't be any longer than the lifecycle of a request-scoped bean, if you write self-contained tests. Remember, there's no need to test the scoping mechanism, it's part of Spring and you can assume it works.

这篇关于在春季测试中请求范围豆的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-29 20:38