我有一个问题,我无法解决。我在互联网和Stackoverflow上搜索过但无法找到解决问题的方法。
我想测试一个Spring MVC Handler拦截器。此拦截器具有“会话”范围bean作为依赖项。
我尽可能地减少了代码。这是代码:
src部分:
@EnableWebMvc
@Configuration
@ComponentScan(basePackages = { "..." })
public class SpringMvcConfiguration extends WebMvcConfigurerAdapter {
@Override
public void addInterceptors(InterceptorRegistry interceptorRegistry) {
interceptorRegistry.addInterceptor(initializeUserLanguageHandler());
}
@Bean
public InitializeUserLanguageHandler initializeUserLanguageHandler() {
return new InitializeUserLanguageHandler();
}
@Bean
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public SessionBean sessionBean() {
return new SessionBean();
}
}
@Component
public class InitializeUserLanguageHandler extends AbstractHandlerInterceptor {
@Autowired
private SessionBean sessionBean;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (sessionBean.getLanguage() == null) {
sessionBean.setLanguage(getUserLanguage());
}
return true;
}
}
测试部分:
@WebAppConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringMvcConfiguration.class)
public class BaseSpringMvcIntegrationTest {
@Resource
protected WebApplicationContext webApplicationContext;
protected MockMvc mockMvc;
@Before
public void setUp() {
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
}
public class InitializeUserLanguageHandlerTest extends BaseSpringMvcIntegrationTest {
@Autowired
private SessionBean sessionBean;
@Autowired
private MockHttpSession mockHttpSession;
@Test
public void testLanguageIsInitializedOnlyOnce() throws Exception {
MockHttpSession mocksession = new MockHttpSession();
// It is null, this is because the interceptor has not been called yet
assertEquals(null, sessionBean.getLanguage());
// This line will call the interceptor and set language to "nl"
mockMvc.perform(get("/").session(mocksession).principal(getUser("nl")));
// It is null, but I expect it to be "nl"
assertEquals(null, sessionBean.getLanguage());
// Let's try again
mockMvc.perform(get("/").session(mocksession).principal(getUser("fr")));
// It is null, but I expect it to be "nl"
assertEquals(null, sessionBean.getLanguage());
}
}
你可以在测试类“InitializeUserLanguageHandlerTest”中看到我有一些断言。
我第一次打电话:
mockMvc.perform(get("/").session(mocksession).principal(getUser()));
执行拦截器中的代码并将语言设置为“nl”。因此,在我的测试中,我希望sessionBean.getLanguage()会返回“nl”,但事实并非如此。我不明白为什么。
所以我再次调用perform,再次执行拦截器代码,并调用sessionBean.getLanguage()返回“nl”。
似乎我有两个SessionBean实例,一个在我的测试中,另一个在源中。但是当我在调试模式下查看Eclipse中的SessionBean变量时,它们具有相同的ID。
如果我将“会话”范围更改为“应用程序”范围,则表明它正常工作。
有人能帮助我吗?
谢谢。
答案 0 :(得分:0)
这是解决问题的一种方法,但不确定它是最好的。
@ContextConfiguration(classes = {SpringMvcConfiguration.class, InitializeUserLanguageHandlerTest.BeanConfig.class})
public class InitializeUserLanguageHandlerTest extends BaseSpringMvcIntegrationTest {
@Configuration
public static class BeanConfig {
@Bean(name = "sessionBean")
public SessionBean sessionBean() {
return new SessionBean();
}
}
...
}