类之前的 Junit(非静态)
是否有任何最佳实践可以让 Junit 在测试文件中执行一次函数,并且它也不应该是静态的。
就像非静态函数上的 @BeforeClass
一样?
这是一个丑陋的解决方案:
@Before void init(){
if (init.get() == false){
init.set(true);
// do once block
}
}
这是我不想做的事情,我正在寻找一个集成的 junit 解决方案。
Are there any best practices to get Junit execute a function once in a test file , and it should also not be static.
like @BeforeClass
on non static function?
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
一个简单的 if 语句似乎也运行得很好:
A simple if statement seems to work pretty well too:
使用空构造函数是最简单的解决方案。您仍然可以重写扩展类中的构造函数。
但这对于所有继承来说并不是最佳的。这就是 JUnit 4 使用注释的原因。
另一种选择是在工厂/util 类中创建一个辅助方法,并让该方法完成工作。
如果您使用 Spring,则应考虑使用
@TestExecutionListeners
注释。像这样的测试:
Spring的
AbstractTestExecutionListener
包含例如您可以重写的空方法:注意:在添加自定义时不要忽略/错过
DependencyInjectionTestExecutionListener
TestExecutionListeners
。如果这样做,所有自动装配都将为null
。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.
Another option is to create a helper method in a factory/util class and let that method do the work.
If you're using Spring, you should consider using the
@TestExecutionListeners
annotation.Something like this test:
Spring's
AbstractTestExecutionListener
contains for example this empty method that you can override:NOTE: DO NOT overlook/miss
DependencyInjectionTestExecutionListener
while adding customTestExecutionListeners
. If you do, all the autowires will benull
.如果您不想为一次性初始化设置静态初始值设定项,并且不特别注重使用 JUnit,请查看 TestNG。 TestNG 支持非静态、一次性初始化,具有多种配置选项,所有这些都使用注释。
在 TestNG 中,这相当于:
对于拆卸,
对于 JUnit 4 的
@Before
和@After
的 TestNG 等效项,您可以使用@BeforeMethod
和@AfterMethod
分别。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.
In TestNG, this would be equivalent to:
For teardown,
For the TestNG equivalent of JUnit 4's
@Before
and@After
, you can use@BeforeMethod
and@AfterMethod
respectively.轻松使用
@BeforeAllMethods
/@AfterAllMethods
注释在实例上下文(非静态)中运行方法,其中所有注入的值都可用。为此有一个特殊的测试库:
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/
唯一的限制:仅适用于春季测试。
(我是这个测试库的开发者)
Easily use
@BeforeAllMethods
/@AfterAllMethods
annotations to run a method inside the instance context (non-static), where all injected values will be available.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://bitbucket.org/radistao/before-after-spring-test-runner/
The only limitation: works only for Spring testing.
(I'm the developer of this testing library)
我从未尝试过,但也许您可以创建一个无参数构造函数并从那里调用您的函数?
I've never tried but maybe you can create a no-argument constructor and call you function from there?
文章讨论了两个非常好的解决方案问题:
The article discuss 2 very nice solutions for this problem:
更新:请参阅 Cherry 的评论,了解为什么下面的建议有缺陷。(我将答案保留在此处而不是删除,因为该评论可能会向其他人提供有用的信息,说明为什么此不起作用。)
如果使用依赖注入(例如 Spring),另一个值得考虑的选项是@PostConstruct
。这将保证依赖注入完成,而构造函数中不会出现这种情况: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't work.)
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:只需使用@BeforeClass:
将
init
设为非静态是没有意义的,因为每个测试都在单独的实例中运行。实例运行的
init
与任何测试的实例都不匹配。您可能希望它成为非静态的唯一原因是在子类中覆盖它,但您可以这样做
也有静态方法。只要使用相同的名称,就只会调用子类的
init
方法。Just use
@BeforeClass
:It doesn't make sense for
init
to be non-static because each test is run in a separate instance. The instancethat
init
is run on would not match the instance of any test.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.