我在我的程序中使用'm trying to write a Unit Test for a simple bean that'来验证表单 . bean使用 @Component
进行批注,并且具有使用 @Value("${this.property.value}") private String thisProperty;
初始化的类变量
我想为这个类中的验证方法编写单元测试,但是,如果可能的话,我想在不使用属性文件的情况下这样做 . 我的理由是,如果我从属性文件中提取的值发生变化,我希望这不会影响我的测试用例 . 我的测试用例是测试验证值的代码,而不是值本身 .
有没有办法在我的测试类中使用Java代码初始化Java类并在该类中填充Spring @Value属性然后使用它来测试?
我确实发现这个似乎很接近的How To,但仍然使用属性文件 . 我宁愿这一切都是Java代码 .
谢谢
6 回答
如果可能,我会尝试在没有Spring Context的情况下编写这些测试 . 如果在没有 spring 的情况下在测试中创建此类,则可以完全控制其字段 .
要设置
@value
字段,可以使用Springs ReflectionTestUtils - 它有一个方法setField来设置私有字段 .@see JavaDoc: ReflectionTestUtils.setField(java.lang.Object, java.lang.String, java.lang.Object)
从Spring 4.1开始,您可以在单元测试类级别上使用
org.springframework.test.context.TestPropertySource
注释在代码中设置属性值 . 即使将属性注入到依赖的bean实例中,也可以使用此方法例如
Note: 必须在Spring上下文中包含
org.springframework.context.support.PropertySourcesPlaceholderConfigurer
的实例Edit 24-08-2017: 如果您使用的是SpringBoot 1.4.0及更高版本,则可以使用@SpringBootTest和@SpringBootConfiguration注释初始化测试 . 更多信息here
对于SpringBoot,我们有以下代码
如果需要,您仍然可以在Spring Context中运行测试,并在Spring配置类中设置所需的属性 . 如果您使用JUnit,请使用SpringJUnit4ClassRunner并为您的测试定义专用配置类:
被测试的课程:
测试类:
以及此测试的配置类:
话虽如此,我不推荐这种方法,我只是在这里添加它以供参考 . 在我看来,更好的方法是使用Mockito跑步者 . 在这种情况下,你根本不在Spring内部运行测试,这更加清晰和简单 .
这似乎有效,虽然仍然有点冗长(我还想要更短的东西):
在配置中添加PropertyPlaceholderConfigurer对我有用 .
}
在测试课上
}
Make your class testable both unitary and in integration
为了能够编写普通单元测试(没有运行 spring 容器)和Spring组件类的集成测试,你必须使这个类可以使用或不使用Spring .
在不需要的情况下在单元测试中运行容器是一种不好的做法,会降低本地构建的速度:您不希望这样做 .
我添加了这个答案,因为这里的答案似乎没有显示出这种区别,所以他们系统地依赖于一个正在运行的容器 .
所以我认为你应该将这个属性定义为类的内部:
到将由Spring注入的构造函数参数:
Unit test example
你可以在不使用Spring的情况下实例化
Foo
并为property
注入任何值,这要归功于构造函数:Integration test example
由于
@SpringBootTest
的properties
属性,您可以以这种简单的方式在Spring Boot的上下文中注入属性:您可以使用替代
@TestPropertySource
但它添加了一个额外的注释:使用Spring(没有Spring Boot),它应该有点复杂但是因为我很长一段时间没有使用没有Spring Boot的Spring,所以我不喜欢说一个愚蠢的事情 .