我使用的是Spring 3.1.4,并尝试使用MockMvc围绕我们的身份验证编写一些集成测试。
我遇到的一个根本问题是因为我没有使用Spring 3.2,我在测试中无法@Autowire
WebApplicationContext
个对象,因此无法使用MockMvcBuilders.webApplicationContextSetup()
,因此我使用xmlConfigSetup
代替。
我似乎已经遇到了多条叉子的道路,这两条叉子都没有解决我的所有问题。
我的配置如下:
@ContextConfiguration(locations = {
"classpath:/test-applicationContext.security.xml",
"classpath:/test-mvc-dispatcher-servlet.xml"
})
@RunWith(SpringJUnit4ClassRunner.class)
public class SecurityTests extends AbstractJUnit4SpringContextTests {
public static final String[] CONTEXT_CONFIG = {
"classpath:/test-applicationContext.security.xml", "classpath:/test-mvc-dispatcher-servlet.xml"
};
@Autowired
private Filter springSecurityFilterChain;
@Before
public void setUp() {
ContextMockMvcBuilder xmlConfigSetup = MockMvcBuilders.xmlConfigSetup(CONTEXT_CONFIG);
this.mockMvc = xmlConfigSetup.addFilters(springSecurityFilterChain).build();
}
这里的优势是我的springSecurityFilterChain
为@Autowired
,因此可以轻松提供给addFilters()
。 缺点是任何其他自动装配的bean都是不同的实例,而不是我的MockMvc配置中的那些,因为我基本上构建了两次servlet上下文。这意味着如果我自动装配UserDetailsService
并在我的集成测试中调整它(添加用户" bob"),那么MockMvc实例就没有它。
选项1:使用上面的配置,我可以访问MockMvc实例中的任何bean吗?我还没有找到办法,这使得"准备"任何集成测试都不可能。
选项2:删除@ContextConfiguration
,然后让MockMvc驱动测试。这似乎更清晰,但我无法弄清楚如何创建/注入Spring Security过滤器链 - 因为它不再自动装配。 (我的bean的无 - 这使得访问UserDetailsService
等其他关键bean也有问题。)
选项3 :我是否可以从WebApplicationContext
超类中的applicationContext
手动装配AbstractJUnit4SpringContextTests
,并提供 this 到MockMvcBuilders.webApplicationContextSetup()
方法?这样做的好处是不需要两个单独的servlet上下文,但是当我没有真正拥有它时,手动构建它似乎特别容易 - 而且我不确定如何将Spring Security过滤器链集成到这个。
我正在寻找有关上述选项(如果有)最可行的建议,以及如何完成这些建议。
不幸的是,升级到更新版本的Spring不是一种选择。
答案 0 :(得分:6)
This post提出了一种将WebApplicationContext
注入JUnit测试的方法。除了指定配置位置外,它们还使用专门用于运行集成测试的自定义上下文加载器。问题是它们的上下文加载器依赖于任何Spring存储库中不再可用的类。但是,它可以从Spring MVC Test Samples中的一些派生出来。
第1步:创建自定义上下文加载器
class TestWebContextLoader extends AbstractContextLoader { ... }
此上下文加载器将用于加载Spring配置文件。
第2步:使用自定义加载程序加载Spring配置文件。
更改
@ContextConfiguration(locations = {
"classpath:/test-applicationContext.security.xml",
"classpath:/test-mvc-dispatcher-servlet.xml" })
到
@ContextConfiguration(loader = TestWebContextLoader.class,
locations = {
"classpath:/test-applicationContext.security.xml",
"classpath:/test-mvc-dispatcher-servlet.xml" })
第3步:将
WebApplicationContext
注入JUnit测试中
public class SecurityTests extends AbstractJUnit4SpringContextTests {
@Autowired
private WebApplicationContext webApplicationContext;
}
第4步:使用注入的
构建模拟WebApplicationContext
public class SecurityTests extends AbstractJUnit4SpringContextTests {
@Autowired
private WebApplicationContext webApplicationContext;
@Before
public void setUp() {
MockMvc mock = MockMvcBuilders.webApplicationContextSetup(webApplicationContext).build();
}
}
我创建了a sample application来演示概念以及上下文加载成功的位置。