是否有任何最佳实践可以让Junit在测试文件中执行一次函数,它也不应该是静态的。
类似非静态函数的@BeforeClass
?
这是一个丑陋的解决方案:
@Before void init(){
if (init.get() == false){
init.set(true);
// do once block
}
}
这是我不想做的事情,我正在寻找一个集成的junit解决方案。
答案 0 :(得分:34)
使用空构造函数是最简单的解决方案。您仍然可以覆盖扩展类中的构造函数。
但它并不是所有继承的最佳选择。这就是JUnit 4使用注释的原因。
另一个选择是在factory / util类中创建一个helper方法,让该方法完成工作。
如果您使用的是Spring,则应考虑使用@TestExecutionListeners
注释。
像这样的测试:
@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({CustomTestExecutionListener.class,
DependencyInjectionTestExecutionListener.class})
@ContextConfiguration("test-config.xml")
public class DemoTest {
Spring的AbstractTestExecutionListener
包含例如您可以覆盖的空方法:
public void beforeTestClass(TestContext testContext) throws Exception {
/* no-op */
}
注意:添加自定义DependencyInjectionTestExecutionListener
时,请勿忽略/错过TestExecutionListeners
。如果您这样做,所有的自动装置都将是null
。
答案 1 :(得分:34)
简单的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;
}
}
...
答案 2 :(得分:18)
如果您不想为一次初始化设置静态初始值设定项,而不是特别关于使用JUnit,请查看TestNG。 TestNG支持使用各种配置选项的非静态一次性初始化,所有这些都使用注释。
在TestNG中,这相当于:
@org.testng.annotations.BeforeClass
public void setUpOnce() {
// One time initialization.
}
对于拆解,
@org.testng.annotations.AfterClass
public void tearDownOnce() {
// One time tear down.
}
对于JUnit 4的@Before
和@After
等效的TestNG,您可以分别使用@BeforeMethod
和@AfterMethod
。
答案 3 :(得分:7)
轻松使用Runnable
/ @BeforeAllMethods
注释在实例上下文(非静态)中运行方法,其中所有注入的值都可用。
有一个特殊的测试库:
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/
唯一限制:仅适用于 Spring 测试。
(我是这个测试库的开发者)
答案 4 :(得分:0)
我从未尝试过,但也许你可以创建一个无参数的构造函数并从那里调用你的函数?
答案 5 :(得分:0)
更新:请参阅Cherry的评论,了解以下建议存在缺陷的原因。(我在这里保留答案而不是删除,因为评论可能会向其他人提供有用的信息,说明为什么会这样做< strong>不工作。)
如果使用依赖注入(例如Spring),另一个值得考虑的选择是 @PostConstruct
。这将保证依赖注入完成,这在构造函数中不是这样的:
@PostConstruct
public void init() {
// One-time initialization...
}
击> <击> 撞击>
答案 6 :(得分:0)
The article讨论了这个问题的2个非常好的解决方案:
答案 7 :(得分:0)
只需使用@BeforeClass
:
@BeforeClass
public static void init() {
}
init
非静态是没有意义的,因为每个测试都在一个单独的实例中运行。实例
运行init
与任何测试的实例都不匹配。
您可能希望它是非静态的唯一原因是在子类中覆盖它,但您可以这样做
用静态方法也是如此。只需使用相同的名称,只会调用子类init
方法。