java 如何使用 SpringApplicationConfiguration 或 ContextConfiguration 加载较小的应用程序部分
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26370743/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use SpringApplicationConfiguration or ContextConfiguration to load smaller app portions
提问by kung_fu_mike
I am working on a spring-boot based project, which is fairly new to me. At present, I am using the @WebApplicationContext annotation to get any of my Junit test to run, as I cannot seem to get the application to boot any other way. My goal in asking this question is to either get a distinct answer to how to avoid it's use, or links to projects use an applicable concept.
我正在开发一个基于 spring-boot 的项目,这对我来说是相当新的。目前,我正在使用 @WebApplicationContext 注释来运行我的任何 Junit 测试,因为我似乎无法以任何其他方式启动应用程序。我提出这个问题的目标是获得关于如何避免使用它的明确答案,或者指向项目的链接使用适用的概念。
My exact goal is: I would like to have a testing configuration which will not load up the entire web application in order to test smaller services and sub sets of classes.
我的确切目标是:我想要一个不会加载整个 Web 应用程序的测试配置,以便测试较小的服务和类的子集。
Example: I currently have a series of 3 assemblers. One is for a parent object, and the other two for child related objects
示例:我目前有一系列 3 个汇编程序。一个用于父对象,另外两个用于子相关对象
@Component
public class ReportResponseAssembler {
@Autowired
private ParameterResponseAssembler parameterResponseAssembler;
@Autowired
private TimeRangeResponseAssembler timeRangeResponseAssembler;
public ReportResponseAssembler makeResponse() {
return new ReportResponseAssembler();
}
}
For testing purposes, I would like to load up just these 3 classes and have them appropriately inject the dependencies into the parent. Something like:
出于测试目的,我只想加载这 3 个类,并让它们适当地将依赖项注入父类。就像是:
public class ReportResponseAssemblerTest {
@Autowired
ReportInstanceResponseAssembler reportResponseAssembler;
@Test
public void testPlaceHolder() {
Assert.assertNotNull(reportResponseAssembler);
}
}
I have attempted something along the lines of:
我尝试了以下方面的内容:
@EnableAutoConfiguration
@ComponentScan(basePackages = { "com.blahpackage.service.assembler" })
@Configuration
public class TestContextConfiguration {}
Then feeding this to SpringApplicationConfiguration, but even with the scan it does not detect the applicable beans for auto injection. Perhaps I need to denote them as @Beans directly in the configuration and return new instances? Are there other good ways? Any links to example projects or explanations you have would be excellent.
然后将其提供给 SpringApplicationConfiguration,但即使进行了扫描,它也不会检测到适用于自动注入的 bean。也许我需要在配置中直接将它们表示为 @Beans 并返回新实例?还有其他好的方法吗?任何指向示例项目或解释的链接都会很棒。
Thank you, any who respond, so much for your time.
谢谢你,任何回应的人,非常感谢你的时间。
采纳答案by geoand
What you are trying to do can easily be done with the following code:
您可以使用以下代码轻松完成您要执行的操作:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = TestContextConfiguration.class)
public class ReportResponseAssemblerTest {
@Autowired
ReportInstanceResponseAssembler reportResponseAssembler;
@Test
public void testPlaceHolder() {
Assert.assertNotNull(reportResponseAssembler);
}
}
@EnableAutoConfiguration
@ComponentScan(basePackages = { "com.blahpackage.service.assembler" })
@Configuration
public class TestContextConfiguration {
}
The three classes you mention need to be under com.blahpackage.service.assembler
and also have to be annotated with some Spring stereotype annotation, like @Component
or @Service
. For example you would have:
您提到的三个类需要在下面,com.blahpackage.service.assembler
并且还必须使用一些 Spring 构造型注释进行注释,例如@Component
or @Service
。例如,您将拥有:
@Component
public class ReportResponseAssembler {
@Autowired
private ParameterResponseAssembler parameterResponseAssembler;
@Autowired
private TimeRangeResponseAssembler timeRangeResponseAssembler;
public ReportResponseAssembler makeResponse() {
return new ReportResponseAssembler();
}
}
@Component
public class ParameterResponseAssembler {
//whatever
}
I would however advise that you use such a test rarely because of the performance implications. What I mean is that if you have a lot of these types of tests, Spring needs to create and destroy a different application context for each one, whereas if you use the same context and tests, Spring can (usually) cache the context. Check out thisblog post for more details
但是,由于性能影响,我建议您很少使用此类测试。我的意思是,如果您有很多此类测试,Spring 需要为每个测试创建和销毁不同的应用程序上下文,而如果您使用相同的上下文和测试,则 Spring 可以(通常)缓存该上下文。查看此博客文章了解更多详情
回答by luboskrnac
I would suggest not to create testing configuration at all. Your integration tests (hopefully you know that unit test shouldn't create Spring context at all) would be testing configuration that isn't used in production.
我建议根本不要创建测试配置。您的集成测试(希望您知道单元测试根本不应该创建 Spring 上下文)将测试未在生产中使用的配置。
I would suggest to create Spring configuration per package/module/integration testing unit. Than you can import these configurations into other contexts via @Import annotation.
我建议为每个包/模块/集成测试单元创建 Spring 配置。您可以通过@Import 注释将这些配置导入到其他上下文中。
Per package approach have huge advantage, that you can specify package private (with default access modifier) beans
每包方法具有巨大的优势,您可以指定包私有(使用默认访问修饰符)bean
@Component
class SomeBeanClass{
}
These can be autowired only by beans from same package. This is handy way how to encapsulate Spring beans.
这些只能由来自同一包的 bean 自动装配。这是封装 Spring bean 的便捷方式。
Such granulated Spring configurations can be easily tested by your integration test in isolation.
这种细化的 Spring 配置可以很容易地由您的集成测试单独进行测试。