@Autowired、@Component 和测试
您将如何集成测试一个经过注释配置和组件扫描且根本没有 XML 配置的 Spring 应用程序?我遇到了麻烦,需要用测试组件替换生产组件,而无需实际诉诸 xml 配置或对所有 @autowired 部分进行反射注入。
示例:
interface A {...}
@Component
class AImpl implements A {
...
}
interface B {...}
@Component
class BImpl implements B {
@Autowired A a;
...
}
interface C {...}
class CImpl implements C {
@Autowired B b;
...
}
然后在我的测试中我想使用 ATestImpl,但我只能访问 C(集成测试 C)。
你会怎样做呢?
How would you go about integration testing a spring application that is annotation-configured and component-scanned and does not have an XML configuration at all? I'm hitting a wall with the need to replace production components with testing components without actually resorting to xml configuration or reflection injections to all the @autowired parts.
Example:
interface A {...}
@Component
class AImpl implements A {
...
}
interface B {...}
@Component
class BImpl implements B {
@Autowired A a;
...
}
interface C {...}
class CImpl implements C {
@Autowired B b;
...
}
then in my test I want to use ATestImpl, but I only have access to C (integration testing C).
How would you go about doing that?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
使用专用的 spring 上下文 XML 文件,在其中使用
ATestImpl
实例覆盖AImpl
。当然,它使用 XML,但我没有看到任何其他解决方案(除了使用ATestImpl
注释类而不是AImpl
重新打包应用程序)Use a dedicated spring context XML file where you override
AImpl
with an instance ofATestImpl
. Of course, it uses XML, but I don't see any other solution (other than repackaging the application with yourATestImpl
annotated class instead of theAImpl
one)Spring 3.1 中的新 Bean Profile 功能通过定义配置文件(例如测试、生产等)解决了交换注入组件进行测试的需要。
博客文章的链接是 此处。 Spring 团队今天发布了 Spring 3.1 的第二个里程碑版本。
The new Bean Profile features in Spring 3.1 address the need to swap injected components for testing by defining profiles e.g. test, production etc.
The link to the blog post is here. The Spring team have today released the second milestone release of Spring 3.1.
您可以对测试使用特殊的组件扫描,排除“正常”类并添加测试类。
如果您有多个不同的测试类,那么它们不应该有
@Component
注解(或 @Service,...)。相反,它们应该通过 XML Bean 声明加载
。因此,您可以为不同的设置使用不同的 XML 文件。You can use a special component scan for your test, that exclude the "normal" class and add the test class.
If you have several different test classes, then they should not have a
@Component
Annotation (or @Service, ...). Instead they should beloaded
by an XML Bean declaration. So you can have different XML files for different setups.使用 Spring 注释配置类,将 @Bean 方法编码为接口。 prod 配置可以在高级包上执行组件扫描以加载 prod 对象,并且测试配置可以单独指定 bean 以返回对象的测试版本。这对于需要伪造服务调用和 DAO 对象的组件测试非常有效。
Using Spring annotation config classes, code the @Bean methods to interfaces. The prod config can perform a componentscan on the high-level package(s) to load the prod objects and the test configs can individually specify beans to return the test versions of your objects. This works very well for component testing where faking service calls and DAO objects is necessary.
利用
@Primary
注解:如果有多个 bean 实现
A
,Spring 将优先选择使用@Primary
注解的 bean。如果你将TestA
类放在/src/test/java
中,它只会在测试执行期间被拾取,在正常上下文启动时 Spring 将不会看到TestA
并仅使用可用的AImpl
。Take advantage of
@Primary
annotation:If there is more than one bean implementing
A
, Spring will prefer the one annotated with@Primary
. If you placeTestA
class in/src/test/java
, it will only be picked up during test execution, on normal context startup Spring won't seeTestA
and use only avaialbleAImpl
.