上课之前的Junit(非静态)
有没有最好的做法来让Junit在testing文件中执行一次函数,而且它也不应该是静态的。
像非静态函数的@BeforeClass
?
这是一个丑陋的解决scheme:
@Before void init(){ if (init.get() == false){ init.set(true); // do once block } }
以及这是我不想做的事情,我正在寻找一个集成的junit解决scheme。
如果您不想为一次初始化设置静态初始化程序,而不是使用JUnit,请查看TestNG。 TestNG支持使用各种configuration选项的非静态,一次性初始化,全部使用注释。
在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
。
使用空的构造函数是最简单的解决scheme。 您仍然可以覆盖扩展类中的构造函数。
但是对于所有的inheritance来说并不是最优的。 这就是为什么JUnit 4使用注释来代替。
另一种方法是在factory / util类中创build一个辅助方法,并让该方法完成工作。
如果你使用Spring,你应该考虑使用@TestExecutionListeners
注解。 像这样的testing:
@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 */ }
一个简单的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; } } ...
我从来没有尝试,但也许你可以创build一个无参的构造函数,并从那里调用你的function?
本文讨论了这个问题的两个非常好的解决scheme:
- 使用自定义Runner的“clean”junit(使用接口,但可以使用自定义注释来扩展它,例如@BeforeInstance)
- Spring之前的Espen提到的执行监听器。
只需使用@BeforeClass
:
@BeforeClass public static void init() { }
init
不是非静态的,因为每个testing都在一个单独的实例中运行。 运行init
的实例不匹配任何testing的实例。
你可能希望它是非静态的唯一原因是在子类中覆盖它,但你也可以用静态方法来做到这一点。 只要使用相同的名称,只会调用子类的init
方法。
更新:请看樱桃评论为什么下面的build议是有缺陷的。 (我现在答案不是删除/编辑,因为评论可能会提供有用的信息,为什么这不起作用)。
另一个值得考虑的select是否使用dependency injection(例如Spring)是@PostConstruct
。 这将保证dependency injection是完整的,在构造函数中不会出现这种情况:
@PostConstruct public void init() { // One-time initialization... }
这里有一个专门的testing库:
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/
可以很容易地使用@BeforeAllMethods
/ @AfterAllMethods
注解在实例上下文(非静态)内运行一个方法,其中所有注入的值都将可用。
唯一的限制:仅适用于Springtesting。
(我是这个testing库的开发者)