gpt4 book ai didi

java - 在 Spring 测试中请求范围内的bean

转载 作者:IT老高 更新时间:2023-10-28 13:46:37 24 4
gpt4 key购买 nike

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

@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 定义:

 <?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'

所以我发现这个博客似乎很有帮助: http://www.javathinking.com/2009/06/no-scope-registered-for-scope-request_5.html

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

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

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

最佳答案

Spring 3.2 或更高版本的解决方案

从 3.2 版开始的 Spring provides support for session/request scoped beans for integration testing .

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = TestConfig.class)
@WebAppConfiguration
public class SampleTest {

@Autowired WebApplicationContext wac;

@Autowired MockHttpServletRequest request;

@Autowired MockHttpSession session;

@Autowired MySessionBean mySessionBean;

@Autowired MyRequestBean myRequestBean;

@Test
public void requestScope() throws Exception {
assertThat(myRequestBean)
.isSameAs(request.getAttribute("myRequestBean"));
assertThat(myRequestBean)
.isSameAs(wac.getBean("myRequestBean", MyRequestBean.class));
}

@Test
public void sessionScope() throws Exception {
assertThat(mySessionBean)
.isSameAs(session.getAttribute("mySessionBean"));
assertThat(mySessionBean)
.isSameAs(wac.getBean("mySessionBean", MySessionBean.class));
}
}

阅读更多:Request and Session Scoped Beans


Spring 3.2 之前的监听器解决方案

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = TestConfig.class)
@TestExecutionListeners({WebContextTestExecutionListener.class,
DependencyInjectionTestExecutionListener.class,
DirtiesContextTestExecutionListener.class})
public class SampleTest {
...
}

WebContextTestExecutionListener.java

public  class WebContextTestExecutionListener extends AbstractTestExecutionListener {
@Override
public void prepareTestInstance(TestContext testContext) {
if (testContext.getApplicationContext() instanceof GenericApplicationContext) {
GenericApplicationContext context = (GenericApplicationContext) testContext.getApplicationContext();
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
beanFactory.registerScope(WebApplicationContext.SCOPE_REQUEST,
new SimpleThreadScope());
beanFactory.registerScope(WebApplicationContext.SCOPE_SESSION,
new SimpleThreadScope());
}
}
}

3.2 之前的 Spring 使用自定义范围的解决方案

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = TestConfig.class, locations = "test-config.xml")
public class SampleTest {

...

}

TestConfig.java

@Configuration
@ComponentScan(...)
public class TestConfig {

@Bean
public CustomScopeConfigurer customScopeConfigurer(){
CustomScopeConfigurer scopeConfigurer = new CustomScopeConfigurer();

HashMap<String, Object> scopes = new HashMap<String, Object>();
scopes.put(WebApplicationContext.SCOPE_REQUEST,
new SimpleThreadScope());
scopes.put(WebApplicationContext.SCOPE_SESSION,
new SimpleThreadScope());
scopeConfigurer.setScopes(scopes);

return scopeConfigurer

}

或者用xml配置

test-config.xml

<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="request">
<bean class="org.springframework.context.support.SimpleThreadScope"/>
</entry>
</map>
<map>
<entry key="session">
<bean class="org.springframework.context.support.SimpleThreadScope"/>
</entry>
</map>
</property>
</bean>

源代码

所有提供的解决方案的源代码:

关于java - 在 Spring 测试中请求范围内的bean,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2411343/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com