Java Junit 课前(非静态)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2825615/
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
Junit before class ( non static )
提问by Roman
Are there any best practices to get Junit execute a function once in a test file , and it should also not be static.
是否有任何最佳实践可以让 Junit 在测试文件中执行一次函数,并且它也不应该是静态的。
like @BeforeClass
on non static function?
喜欢@BeforeClass
非静态函数?
Here is an ugly solution :
这是一个丑陋的解决方案:
@Before void init(){
if (init.get() == false){
init.set(true);
// do once block
}
}
well this is something i dont want to do , and i am looking for an integrated junit solution.
好吧,这是我不想做的事情,我正在寻找一个集成的 junit 解决方案。
采纳答案by Kartik
If you don't want to set up static initializers for one time initialization and are not particular about using JUnit, take a look at TestNG. TestNG supports non-static, one-time initialization with a variety of configuration options, all using annotations.
如果你不想设置静态初始化器一次性初始化并且对使用JUnit不讲究,可以看看TestNG。TestNG 支持非静态、一次性初始化,具有多种配置选项,全部使用注解。
In TestNG, this would be equivalent to:
在 TestNG 中,这相当于:
@org.testng.annotations.BeforeClass
public void setUpOnce() {
// One time initialization.
}
For teardown,
对于拆解,
@org.testng.annotations.AfterClass
public void tearDownOnce() {
// One time tear down.
}
For the TestNG equivalent of JUnit 4's @Before
and @After
, you can use @BeforeMethod
and @AfterMethod
respectively.
对于 JUnit 4@Before
和的 TestNG 等价物@After
,您可以分别使用@BeforeMethod
和@AfterMethod
。
回答by Roman
I've never tried but maybe you can create a no-argument constructor and call you function from there?
我从未尝试过,但也许您可以创建一个无参数构造函数并从那里调用函数?
回答by Espen
To use an empty constructor is the easiest solution. You can still override the constructor in the extended class.
使用空构造函数是最简单的解决方案。您仍然可以覆盖扩展类中的构造函数。
But it's not optimal with all the inheritance. That's why JUnit 4 uses annotations instead.
但是对于所有的继承来说,它并不是最优的。这就是 JUnit 4 使用注释的原因。
Another option is to create a helper method in a factory/util class and let that method do the work.
另一种选择是在 factory/util 类中创建一个辅助方法,并让该方法完成工作。
If you're using Spring, you should consider using the @TestExecutionListeners
annotation.
Something like this test:
如果您使用的是 Spring,您应该考虑使用@TestExecutionListeners
注解。像这样的测试:
@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({CustomTestExecutionListener.class,
DependencyInjectionTestExecutionListener.class})
@ContextConfiguration("test-config.xml")
public class DemoTest {
Spring's AbstractTestExecutionListener
contains for example this empty method that you can override:
Spring'sAbstractTestExecutionListener
包含例如这个你可以覆盖的空方法:
public void beforeTestClass(TestContext testContext) throws Exception {
/* no-op */
}
NOTE:DO NOT overlook/miss DependencyInjectionTestExecutionListener
while adding custom TestExecutionListeners
. If you do, all the autowires will be null
.
注意:不要忽视/小姐DependencyInjectionTestExecutionListener
,同时添加自定义TestExecutionListeners
。如果你这样做,所有的自动装配将是null
.
回答by Upgradingdave
A simple if statement seems to work pretty well too:
一个简单的 if 语句似乎也很有效:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:test-context.xml"})
public class myTest {
public static boolean dbInit = false;
@Autowired
DbUtils dbUtils;
@Before
public void setUp(){
if(!dbInit){
dbUtils.dropTables();
dbUtils.createTables();
dbInit = true;
}
}
...
回答by Steve Chambers
UPDATE: Please see the comment by Cherry for why the suggestion below is flawed.(Am keeping the answer on here rather than deleting as the comment may provide useful information to others as to why this doesn'twork.)
更新:请参阅 Cherry 的评论,了解为什么下面的建议有缺陷。(我将答案保留在这里而不是删除,因为评论可能会向其他人提供有用的信息,说明为什么这不起作用。)
Another option worth considering if using dependency injection (e.g. Spring) is @PostConstruct
. This will guarantee dependency injection is complete, which wouldn't be the case in a constructor:
如果使用依赖注入(例如 Spring),另一个值得考虑的选项是@PostConstruct
. 这将保证依赖注入是完整的,在构造函数中不会出现这种情况:
@PostConstruct
public void init() {
// One-time initialization...
}
@PostConstruct
public void init() {
// One-time initialization...
}
回答by kedzi
The articlediscuss 2 very nice solutions for this problem:
这篇文章讨论了这个问题的 2 个非常好的解决方案:
- "clean" junit with custom Runner (using interface but you could extend it with a custom annotation e.g. @BeforeInstance)
- Spring execution listeners as mentioned by Espen before.
- 带有自定义 Runner 的“清理”junit(使用接口,但您可以使用自定义注释对其进行扩展,例如 @BeforeInstance)
- Espen 之前提到的 Spring 执行侦听器。
回答by fgb
Just use @BeforeClass
:
只需使用@BeforeClass
:
@BeforeClass
public static void init() {
}
It doesn't make sense for init
to be non-static because each test is run in a separate instance. The instance
that init
is run on would not match the instance of any test.
init
非静态是没有意义的,因为每个测试都在单独的实例中运行。该实例init
的运行将不匹配任何测试的实例。
The only reason that you might want it to be non-static is to override it in subclasses, but you can do this
with static methods too. Just use the same name, and only the subclass init
method will be called.
您可能希望它是非静态的唯一原因是在子类中覆盖它,但您也可以使用静态方法来做到这一点。只需使用相同的名称,并且只会init
调用子类方法。
回答by radistao
Easily use @BeforeAllMethods
/@AfterAllMethods
annotations to run a method inside the instance context (non-static), where all injected values will be available.
轻松使用@BeforeAllMethods
/@AfterAllMethods
注释在实例上下文(非静态)中运行方法,其中所有注入的值都可用。
There is a special testing library for this:
为此有一个特殊的测试库:
https://mvnrepository.com/artifact/org.bitbucket.radistao.test/before-after-spring-test-runner/0.1.0
https://mvnrepository.com/artifact/org.bitbucket.radistao.test/before-after-spring-test-runner/0.1.0
https://bitbucket.org/radistao/before-after-spring-test-runner/
https://bitbucket.org/radistao/before-after-spring-test-runner/
The only limitation: works only for Springtesting.
唯一的限制:仅适用于Spring测试。
(I'm the developer of this testing library)
(我是这个测试库的开发者)