Mocking/autowiring 豆与 Spring 3.1.x 和 MockMvc
Mocking/autowiring beans with Spring 3.1.x and MockMvc
我正在使用 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 实例中的任何 beans 吗?我还没有找到一种方法,这使得 "prepping" 无法进行任何集成测试。
选项 2: 删除 @ContextConfiguration
并让 MockMvc 驱动测试。这看起来更干净,但我不知道如何 create/inject 一个 Spring 安全过滤器链 - 因为它不再自动装配。 (None 我的 bean 是 - 这使得访问其他关键 bean,如 UserDetailsService
也有问题。)
选项 3: 我可以手动装配一个 WebApplicationContext
来包装 AbstractJUnit4SpringContextTests
超类中的 applicationContext
,并提供 this 到 MockMvcBuilders.webApplicationContextSetup()
方法?这具有不需要两个单独的 servlet 上下文的优点,但是当我真的没有时手动构建它似乎特别 hacky - 而且我不确定如何将 Spring 安全过滤器链集成到这也行。
我正在寻求有关上述选项中哪些(如果有)最可行以及如何实现的建议。
不幸的是,升级到 Spring 的较新版本不是一个选项。
This post from the Spring team proposes a way to inject the WebApplicationContext
into JUnit tests. They use a custom context loader specifically implemented for running integration tests, in addition to specifying the configuration location. The trouble is that their context loader depends on a class that is no longer available in any of the Spring repositories. However, it can be derived from some of the Spring MVC Test Samples.
Step 1: Create a custom context loader
class TestWebContextLoader extends AbstractContextLoader { ... }
此上下文加载器将用于加载您的 Spring 配置文件。
Step 2: Use the custom loader to load the Spring configuration files.
改变
@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" })
Step 3: Inject WebApplicationContext
into your JUnit tests
public class SecurityTests extends AbstractJUnit4SpringContextTests {
@Autowired
private WebApplicationContext webApplicationContext;
}
Step 4: Build a mock using the injected WebApplicationContext
public class SecurityTests extends AbstractJUnit4SpringContextTests {
@Autowired
private WebApplicationContext webApplicationContext;
@Before
public void setUp() {
MockMvc mock = MockMvcBuilders.webApplicationContextSetup(webApplicationContext).build();
}
}
我创建了 a sample application 来演示概念以及上下文成功加载的位置。
我正在使用 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 实例中的任何 beans 吗?我还没有找到一种方法,这使得 "prepping" 无法进行任何集成测试。
选项 2: 删除 @ContextConfiguration
并让 MockMvc 驱动测试。这看起来更干净,但我不知道如何 create/inject 一个 Spring 安全过滤器链 - 因为它不再自动装配。 (None 我的 bean 是 - 这使得访问其他关键 bean,如 UserDetailsService
也有问题。)
选项 3: 我可以手动装配一个 WebApplicationContext
来包装 AbstractJUnit4SpringContextTests
超类中的 applicationContext
,并提供 this 到 MockMvcBuilders.webApplicationContextSetup()
方法?这具有不需要两个单独的 servlet 上下文的优点,但是当我真的没有时手动构建它似乎特别 hacky - 而且我不确定如何将 Spring 安全过滤器链集成到这也行。
我正在寻求有关上述选项中哪些(如果有)最可行以及如何实现的建议。
不幸的是,升级到 Spring 的较新版本不是一个选项。
This post from the Spring team proposes a way to inject the WebApplicationContext
into JUnit tests. They use a custom context loader specifically implemented for running integration tests, in addition to specifying the configuration location. The trouble is that their context loader depends on a class that is no longer available in any of the Spring repositories. However, it can be derived from some of the Spring MVC Test Samples.
Step 1: Create a custom context loader
class TestWebContextLoader extends AbstractContextLoader { ... }
此上下文加载器将用于加载您的 Spring 配置文件。
Step 2: Use the custom loader to load the Spring configuration files.
改变
@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" })
Step 3: Inject
WebApplicationContext
into your JUnit tests
public class SecurityTests extends AbstractJUnit4SpringContextTests {
@Autowired
private WebApplicationContext webApplicationContext;
}
Step 4: Build a mock using the injected
WebApplicationContext
public class SecurityTests extends AbstractJUnit4SpringContextTests {
@Autowired
private WebApplicationContext webApplicationContext;
@Before
public void setUp() {
MockMvc mock = MockMvcBuilders.webApplicationContextSetup(webApplicationContext).build();
}
}
我创建了 a sample application 来演示概念以及上下文成功加载的位置。