java 如何在静态@BeforeClass 中自动装配字段?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29340286/
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 autowire field in static @BeforeClass?
提问by membersound
@RunWith(SpringJUnit4ClassRunner.class)
public void ITest {
@Autowired
private EntityRepository dao;
@BeforeClass
public static void init() {
dao.save(initialEntity); //not possible as field is not static
}
}
How can I have my service injected already in the static init class?
如何将我的服务注入到静态 init 类中?
采纳答案by Nenad Bozic
It looks to me that you are trying to populate DB before tests.
在我看来,您正在尝试在测试之前填充数据库。
I would give a try to two options:
我会尝试两种选择:
- If you can extract initial scripts to sql file (if that is option for you without using repository bean) you can use this approachand annotate your test with
@Sql
- You can explore DbUnitand here is link to spring dbunit connectorwhich is doing exactly that and helping you populate DB before tests. Here is a github linkfor integrating between spring test framework and dbunit. After you do that you have
@DatabaseSetup
and@DatabaseTearDown
which will do thing on DB you need
- 如果您可以将初始脚本提取到 sql 文件(如果您可以选择不使用存储库 bean),则可以使用此方法并使用
@Sql
- 您可以探索DbUnit,这里是spring dbunit 连接器的链接,它正是这样做的,并帮助您在测试前填充数据库。这是一个用于在 spring 测试框架和 dbunit 之间集成的github 链接。当你做,你必须
@DatabaseSetup
和@DatabaseTearDown
将做的事情DB你需要
I know that this does not answer how to inject bean in static @BeforeClass
but form code it looks it is solving your problem.
我知道这并没有回答如何在静态中注入 bean,@BeforeClass
但它看起来正在解决您的问题的表单代码。
Update:I recently run into same problem in my project and dug out this articlewhich helped me and I think it is elegant way of dealing with this type of problem. You can extend SpringJUnit4ClassRunner
with listener which can do instance level setup with all your defined beans.
更新:我最近在我的项目中遇到了同样的问题,并挖出了这篇对我有帮助的文章,我认为这是处理此类问题的优雅方式。您可以SpringJUnit4ClassRunner
使用监听器进行扩展,它可以使用您定义的所有 bean 进行实例级设置。
回答by Narain Mittal
One workaround that I have been using to get this working is to use @Before
with a flag to skip it being executed for each testcase
我一直在使用的一种解决方法是使用@Before
一个标志来跳过它为每个测试用例执行
@RunWith(SpringJUnit4ClassRunner.class)
public class BaseTest {
@Autowired
private Service1 service1;
@Autowired
private Service2 service2;
private static boolean dataLoaded = false;
@Before
public void setUp() throws Exception {
if (!dataLoaded) {
service1.something();
service2.somethingElse();
dataLoaded = true;
}
}
}
回答by Vladtn
With Junit 5 you can do this (@BeforeAll instead of @BeforeClass)
使用 Junit 5 你可以做到这一点(@BeforeAll 而不是 @BeforeClass)
public void ITest {
@Autowired
private EntityRepository dao;
@BeforeAll
public static void init(@Autowired EntityRepository dao) {
dao.save(initialEntity); //possible now as autowired function parameter is used
}
}
By leaving the field it means it can be used in other tests
离开该领域意味着它可以用于其他测试
回答by yeralin
UPD for Spring 2.x versions.
Spring 2.x 版本的 UPD。
Spring 2.x supports new feature a SpringExtension
for Junit 5 Jupiter, where all you have to do is:
Spring 2.x 支持SpringExtension
Junit 5 Jupiter 的新特性 a ,您所要做的就是:
Declare your test class with
@ExtendWith(SpringExtension.class)
Inject your
@BeforeAll
(replacement for@BeforeClass
in JUnit 5) with the bean
声明你的测试类
@ExtendWith(SpringExtension.class)
使用 bean注入您的
@BeforeAll
(替代@BeforeClass
JUnit 5 中的)
For example:
例如:
@ExtendWith(SpringExtension.class)
...
public void ITest {
@BeforeAll
public static void init(@Autowired EntityRepository dao) {
dao.save(initialEntity);
}
}
Assuming you correctly configured JUnit 5 Jupiter with Spring 2.x
假设您使用 Spring 2.x 正确配置了 JUnit 5 Jupiter
More about it here: https://docs.spring.io/spring/docs/current/spring-framework-reference/testing.html#testcontext-junit-jupiter-extension
更多关于它的信息:https: //docs.spring.io/spring/docs/current/spring-framework-reference/testing.html#testcontext-junit-jupiter-extension
回答by musikele
To answer this question we should recap Spring 2.x versions.
要回答这个问题,我们应该回顾一下 Spring 2.x 版本。
If you want to "autowire" a bean in your @BeforeTest
class you can use the ApplicationContext
interface. Let's see an example:
如果你想在你的@BeforeTest
类中“自动装配”一个 bean,你可以使用该ApplicationContext
接口。让我们看一个例子:
@BeforeClass
public static void init() {
ApplicationContext context = new ClassPathXmlApplicationContext("application-context.xml");
EntityRepository dao2 = (EntityRepository) context.getBean("dao");
List<EntityRepository> all = dao2.getAll();
Assert.assertNotNull(all);
}
What's happening: using the ClassPathXmlApplicationContext
we are instantiating all beans contained in the application-context.xml
file.
发生了什么:使用ClassPathXmlApplicationContext
我们正在实例化application-context.xml
文件中包含的所有 bean 。
With context.getBean()
we read the bean specified (it must match the name of the bean!); and then you can use it for your initialization.
随着context.getBean()
我们读指定的豆(必须bean的名称相匹配!); 然后您可以将其用于初始化。
You should give to the bean another name (that's the dao2
!) otherwise Spring normal "autowired" cannot work on the predefined bean.
你应该给 bean 另一个名字(那就是dao2
!)否则 Spring 正常的“自动装配”不能在预定义的 bean 上工作。
As a side note, if your test extends AbstractTransactionalJUnit4SpringContextTests
you can do some initialization using executeSqlScript(sqlResourcePath, continueOnError)
; method, so you don't depend on a class/method that you also have to test separately.
作为旁注,如果您的测试扩展,AbstractTransactionalJUnit4SpringContextTests
您可以使用executeSqlScript(sqlResourcePath, continueOnError)
;进行一些初始化。方法,因此您不依赖于您还必须单独测试的类/方法。