使用 @ContextConfiguration 在 JUnit 上使用不同的构造函数参数测试 Spring 个 bean
Test Spring beans with different constructor args over JUnit using @ContextConfiguration
问题描述:
我希望用户在 spring XML 配置上使用自定义配置文件配置 spring bean,如下所示:
请注意,只有字符串应该由用户配置,所有其他 bean 都应该在用户不知情的情况下被@Autowired!
<bean class="com.my.group.Provider">
<constructor-arg value="config1.proprietary"/>
<constructor-arg value="config2.proprietary"/>
</bean>
Provider
对象看起来(简化)如下:
public class Provider {
@Autowired
private Foo foo;
private final String[] configNames;
public Provider(final String... configs) {
this.configNames = Preconditions.checkNotNull(configs, "Provided configs must not be null!");
}
public List<Configs> getConfigs() {
return new foo.create(configNames); // here is more logic that I would actually like to test... (not just methods called on foo)
}
}
我的问题是:
如何使用各种不同的字符串输入测试此解决方案,以便所有测试都可以进入一个 JUnit 测试 class? 顺便说一句:我想避免反思...
(下面的单元测试说明了我的意思。他们已经有能力做我想做的事,但他们使用了反射。)
到目前为止我做了什么
之后使用反射来更改字段内容,但说实话这 一点也不性感 :
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {ProviderTest.MyContext.class})
public class ProviderTest {
@Autowired
private Provider sut;
@Test
public void provide_oneConfig() throws NoSuchFieldException, IllegalAccessException {
setConfigFilesViaReflection(sut, "config1.proprietary"");
// When
List<Config> configs = sut.getConfigs();
// Then
assertEquals(1, configs.size());
}
@Test
public void provide_twoConfigs() throws NoSuchFieldException, IllegalAccessException {
setConfigFilesViaReflection(sut, "config1.proprietary", config2.proprietary");
// When
List<Config> configs = sut.getConfigs();
// Then
assertEquals(2, configs.size());
}
private void setConfigFilesViaReflection(final Provider sut, final String... configs) throws NoSuchFieldException,
IllegalAccessException {
Field configNamesField = Provider.class.getDeclaredField("configNames");
configNamesField.setAccessible(true);
configNamesField.set(sut, configs);
}
@Configuration
public static class MyContext {
@Bean
Provider provider() {
return new Provider("willBeOverridenByReflection");
}
@Bean
Foo foo() {
return new Foo(); // this one got mocked in my test
}
}
有时问问题有助于更努力地搜索。
@Qualifier
/ @Resource
注释可以创建多个 bean,并像这样在每个测试中选择它们:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {ProviderTest.MyContext.class})
public class ProviderTest {
@Autowired
@Qualifier("bar") // could also be @Resource (without @Autowired)
private Provider sut;
@Resource(name="baz")
private Provider sut2; // could also be @Qualifier(with @Autowired)
@Test
public void provide_oneConfig() throws NoSuchFieldException, IllegalAccessException {
// When
List<Config> configs = sut.getConfigs();
// Then
assertEquals(1, configs.size());
}
@Test
public void provide_twoConfigs() throws NoSuchFieldException, IllegalAccessException {
// When
List<Config> configs = sut2.getConfigs();
// Then
assertEquals(2, configs.size());
}
@Configuration
public static class MyContext {
@Bean("bar")
Provider providerBar() {
return new Provider"config1.proprietary");
}
@Bean("baz")
Provider providerBaz() {
return new Provider("config1.proprietary", "config2.proprietary");
}
@Bean
Foo foo() {
return new Foo(); // this one got mocked in my test
}
}
在这里找到我的答案:Autowiring two different beans of same class
问题描述:
我希望用户在 spring XML 配置上使用自定义配置文件配置 spring bean,如下所示: 请注意,只有字符串应该由用户配置,所有其他 bean 都应该在用户不知情的情况下被@Autowired!
<bean class="com.my.group.Provider">
<constructor-arg value="config1.proprietary"/>
<constructor-arg value="config2.proprietary"/>
</bean>
Provider
对象看起来(简化)如下:
public class Provider {
@Autowired
private Foo foo;
private final String[] configNames;
public Provider(final String... configs) {
this.configNames = Preconditions.checkNotNull(configs, "Provided configs must not be null!");
}
public List<Configs> getConfigs() {
return new foo.create(configNames); // here is more logic that I would actually like to test... (not just methods called on foo)
}
}
我的问题是:
如何使用各种不同的字符串输入测试此解决方案,以便所有测试都可以进入一个 JUnit 测试 class? 顺便说一句:我想避免反思...
(下面的单元测试说明了我的意思。他们已经有能力做我想做的事,但他们使用了反射。)
到目前为止我做了什么
之后使用反射来更改字段内容,但说实话这 一点也不性感 :
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {ProviderTest.MyContext.class})
public class ProviderTest {
@Autowired
private Provider sut;
@Test
public void provide_oneConfig() throws NoSuchFieldException, IllegalAccessException {
setConfigFilesViaReflection(sut, "config1.proprietary"");
// When
List<Config> configs = sut.getConfigs();
// Then
assertEquals(1, configs.size());
}
@Test
public void provide_twoConfigs() throws NoSuchFieldException, IllegalAccessException {
setConfigFilesViaReflection(sut, "config1.proprietary", config2.proprietary");
// When
List<Config> configs = sut.getConfigs();
// Then
assertEquals(2, configs.size());
}
private void setConfigFilesViaReflection(final Provider sut, final String... configs) throws NoSuchFieldException,
IllegalAccessException {
Field configNamesField = Provider.class.getDeclaredField("configNames");
configNamesField.setAccessible(true);
configNamesField.set(sut, configs);
}
@Configuration
public static class MyContext {
@Bean
Provider provider() {
return new Provider("willBeOverridenByReflection");
}
@Bean
Foo foo() {
return new Foo(); // this one got mocked in my test
}
}
有时问问题有助于更努力地搜索。
@Qualifier
/ @Resource
注释可以创建多个 bean,并像这样在每个测试中选择它们:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {ProviderTest.MyContext.class})
public class ProviderTest {
@Autowired
@Qualifier("bar") // could also be @Resource (without @Autowired)
private Provider sut;
@Resource(name="baz")
private Provider sut2; // could also be @Qualifier(with @Autowired)
@Test
public void provide_oneConfig() throws NoSuchFieldException, IllegalAccessException {
// When
List<Config> configs = sut.getConfigs();
// Then
assertEquals(1, configs.size());
}
@Test
public void provide_twoConfigs() throws NoSuchFieldException, IllegalAccessException {
// When
List<Config> configs = sut2.getConfigs();
// Then
assertEquals(2, configs.size());
}
@Configuration
public static class MyContext {
@Bean("bar")
Provider providerBar() {
return new Provider"config1.proprietary");
}
@Bean("baz")
Provider providerBaz() {
return new Provider("config1.proprietary", "config2.proprietary");
}
@Bean
Foo foo() {
return new Foo(); // this one got mocked in my test
}
}
在这里找到我的答案:Autowiring two different beans of same class