java before after_[深入JUnit] @Before, @After, @Test的秘密

最近对JUnit和Mockito的内部实现比较感兴趣,将在接下来的一段时间,和大家一起深入代码细节。

王侯将相,宁有种乎 (JUnit也没啥Magic吧)

阅读前提

听说过Java Annotation

使用过JUnit

知道@Before, @After, @Test

对JUnit的内部实现有兴趣

代码版本:junit 4.12

代码搜索工具: http://grepcode.com/

常用符号

_: 用来略去代码段中无关紧要的parameter

...: 用来略去无关紧要的代码实现

Example

下面是一个很简单的JUunit Test Class

public class SampleTest {

@Before

protected void setUp(){ ... }

@Test

public void test1(){ ... }

@After

public void tearDown(){ ... }

}

本文要解答的问题:@Before, @Test, @After如何影响test workflow的?

Q&A

Q1. 如何提取一个函数的Annotation信息?

A: 任何Java提供了Method::getDeclaredAnnotations()

Q2. 如何把SampleTest里的methods都罗列出来?

A: Java提供了Class::getDeclaredMethods()

Q3: @Before, @Test, @After的执行顺序如何保证的?

A: 在junit的BlockJUnit4ClassRunner class中有一段代码:

Statement statement = methodInvoker(method, _);

statement = withBefores(method, _, statement);

statement = withAfters(method, _, statement);

Statement可以看做是一个函数封装(Functional Interface),内部只有一个execute()函数。method是被@Test修饰的测试函数(本例中的test1()),withBefores把SampleClass中被@Before修饰的所有函数找出来,然后封装成一个新的Statement。

//比如说,可以用下面的naive实现

void withBefores(Method m, _, Statement statement) {

// 利用Q1和Q2的知识点把@Before修饰的函数都找出来

List befores = ...

return new Statement{

@Override

public execute() {

for (Method b : befores) {

b.execute();

}

m.execute();

}

}

}

Q4: Q3中的BlockJUnit4ClassRunner和SampleTest搅合到一起的?

A: 请自己去看BlockJUnit4ClassRunner的constructor的parameter是什么。

Summary

利用Java原生的getDeclaredAnnotations和getDeclaredMethods,可以轻松地得到测试类SampleTest中函数的annotations。

JUnit用一个Statement来做把setUp(),test1(),以及tearDown()封装到一起,并保证其执行顺序。

References

下期内容

BlockJUnit4ClassRunner又被谁调用了呢?

运行unit test的入口在哪里?

请看:[深入JUnit] 测试运行的入口

ae5fbe5f43fcb8d8c626a3fd282ed9ea.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值