spring 这是做什么的:@RunWith(SpringJUnit4ClassRunner.class)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25317009/
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
What does this do: @RunWith(SpringJUnit4ClassRunner.class)
提问by Jay Vee
What does this annotation do?
When would I want to use it?
When would I not want to use it?
这个注解有什么作用?
我什么时候想使用它?
我什么时候不想使用它?
@RunWith(SpringJUnit4ClassRunner.class)
I can find more usages of this when I Google and do not find a 101 explanation as to what this annotation is supposed to communicate to me or when/why I would use it?
当我谷歌时,我可以找到更多的用法,但没有找到 101 解释这个注释应该传达给我什么,或者我何时/为什么要使用它?
回答by Ricardo Veguilla
The annotation is used to configure a unit test that required Spring's dependency injection.
该注解用于配置需要 Spring 依赖注入的单元测试。
From Spring Reference - 10. Unit Testing:
10.1 Creating a Unit Test Class
In order for the unit test to run a batch job, the framework must load the job's ApplicationContext. Two annotations are used to trigger this:
@RunWith(SpringJUnit4ClassRunner.class): Indicates that the class should use Spring's JUnit facilities.
@ContextConfiguration(locations = {...}): Indicates which XML files contain the ApplicationContext.
10.1 创建单元测试类
为了让单元测试运行批处理作业,框架必须加载作业的 ApplicationContext。使用两个注释来触发:
@RunWith(SpringJUnit4ClassRunner.class):表示该类应该使用 Spring 的 JUnit 设施。
@ContextConfiguration(locations = {...}):指示哪些 XML 文件包含 ApplicationContext。
回答by Joman68
If you are using annotations rather than XML files, then any class that you are unit testing that requires Spring dependency injection needs to be put into the @ContextConfigurationannotation. For example:
如果您使用的是注解而不是 XML 文件,那么您正在单元测试的任何需要 Spring 依赖注入的类都需要放入@ContextConfiguration注解中。例如:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = FooManager.class)
class FooManagerTest {
@Autowired
FooManager fooManager;
Now when you use fooManagerin a unit test it will have have a Spring context setup for it.
现在,当您在单元测试中使用fooManager 时,它将为其设置一个 Spring 上下文。
If fooManagerautowires in any beans then those bean's classes also need to be in the @ContextConfigurationannotation. So if the FooManagerbean autowires in a FooReporterbean:
如果fooManager在任何 bean 中自动装配,那么这些 bean 的类也需要在@ContextConfiguration注释中。因此,如果FooManager在豆autowires FooReporter豆:
@ContextConfiguration(classes = {FooManager.class, FooReporter.class})
If the beans that fooManagerautowires in contain state, then you will likely want to reset the state of those beans for each test. In that case you can add the @DirtiesContextannotation to your test class:
如果fooManager自动装配的 bean 包含状态,那么您可能希望为每个测试重置这些 bean 的状态。在这种情况下,您可以将@DirtiesContext注释添加到您的测试类中:
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
If the fooManageror any of its autowired beans reads Spring config then you need to add an initializerslist to the @ContextConfigurationannotation, that contains the ConfigFileApplicationContextInitializerclass:
如果fooManager或其任何自动装配的 bean 读取 Spring 配置,那么您需要向注释添加一个初始化列表@ContextConfiguration,其中包含ConfigFileApplicationContextInitializer类:
@ContextConfiguration(classes = FooManager.class, initializers = ConfigFileApplicationContextInitializer.class)
回答by Joman68
To answer the when you would and wouldn't want to use it part of the question.
回答您何时想要和不想使用它的问题的一部分。
When to use SpringJUnit4ClassRunner
何时使用 SpringJUnit4ClassRunner
IMO SpringJUnit4ClassRunner should be used very sparingly. There is a significant overhead involved with starting up a Spring container to run a unit test.
IMO SpringJUnit4ClassRunner 应该非常谨慎地使用。启动 Spring 容器以运行单元测试涉及大量开销。
I typically use SpringJUnit4ClassRunner to test:
我通常使用 SpringJUnit4ClassRunner 来测试:
- that components are injected (auto-wired) as expected
- that configuration data is injected as expected
- 组件按预期注入(自动连接)
- 配置数据按预期注入
When you are injecting components issues can arise if the @Qualifierannotation is not used or used incorrectly, for example.
例如,当您注入组件时,如果@Qualifier未使用或不正确使用注释,则可能会出现问题。
When loading configuration from multiple yaml files you may want to test that maps are being merged as expected, with the appropriate overrides occurring.
从多个 yaml 文件加载配置时,您可能想要测试映射是否按预期合并,并发生了适当的覆盖。
At the very least I always have a simple SpringJUnit4ClassRunner test as a sanity check that the Spring container starts up OK.
至少我总是有一个简单的 SpringJUnit4ClassRunner 测试,作为对 Spring 容器启动正常的健全性检查。
When not to use SpringJUnit4ClassRunner
何时不使用 SpringJUnit4ClassRunner
I would not use SpringJUnit4ClassRunner to test the non-Spring related functionality in my code under test. Which in my experience means most of the functionality.
我不会使用 SpringJUnit4ClassRunner 来测试我的被测代码中的非 Spring 相关功能。根据我的经验,这意味着大部分功能。
So this means that any autowired components and injected config data needs to be mocked. This can mean quite a bit of setup code for your unit tests. However this setup code only needs to be written once for all the tests in your class under test. It is also much quicker to run unit tests with mocked components.
所以这意味着需要模拟任何自动装配的组件和注入的配置数据。这可能意味着您的单元测试需要相当多的设置代码。然而,这个设置代码只需要为被测类中的所有测试编写一次。使用模拟组件运行单元测试也更快。
I keep the mocking simple and use Spock to mock the components. Example groovy code:
我保持模拟简单并使用 Spock 来模拟组件。示例常规代码:
import spock.lang.Specification
class FooManagerTest extends Specification {
FooManager cut
void createMockFooReporter() {
FooReporter mockFooReporter = Mock(FooReporter)
mockFooReporter.fooFormatter = Mock(FooFormatter)
}
void setup() {
cut = new FooManager()
cut.fooReporter = createMockFooReporter()
}
void "Basic test"() {
// Do a basic test using 'cut'
}
}
In this example the class under test FooManagerhas an autowired FooReporterwhich itself contains an autowired FooFormatter.
在这个例子中,被测类FooManager有一个 autowired FooReporter,它本身包含一个 autowired FooFormatter。

