前面一篇介绍期待异常处理,说了一下新的注解@Rule, 这篇来学习一下Rule
1.Rule
JUnit有了Rule,才使得有更多的扩展性,能做更多的功能测试。@Rule的特点是:在一个class中所有的@Test标注过的测试方法都会共享这个Rule,例如定义一个Timeout,所有方法运行都会自动检测是否超时。
官方wiki关于rules介绍:https://github.com/junit-team/junit4/wiki/Rules
场景的rule,rule有很多,列举一个常见的
TemporaryFolder
ExternalResource
ErrorCollector
Verifier
TestWatcher
TestName
Timeout
ExpectedException
RuleChain
@ClassRule
最后一个ClassRule是用来管理多个class的rule,我也没用过。
2.Rule练习
前面一篇其实练习过ExpectedException, 这篇来一个Timeout练习,这个Timeout和在@Test(Timeout=20)不一样,这个Timeout功能更强大,作用范围是当前测试类的全部的测试用例。
我们在TrackingServiceTests.java这个测试类来试试这个Rule和Timeout
package test;
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.rules.Timeout;
import com.anthony.protein.InvalidGoalException;
import com.anthony.protein.TrackingService;
public class TrackingServiceTests {
private TrackingService ts;
@BeforeClass
public static void before() {
System.out.println("Before class, Onln Once");
}
@AfterClass
public static void after() {
System.out.println("After class, only once");
}
@Before
public void setup() {
System.out.println("Before Method");
ts = new TrackingService();
}
@After
public void tearDown() {
System.out.println("After Method");
}
@Test
@Category(GoodCategoryTest.class)
public void newTrackingServiceTotalIsZero() {
assertEquals("Tracking service total was not zero", 0, ts.getTotal());
}
@Test
@Category(GoodCategoryTest.class)
public void whenAddingProteinTotalIsIncreaseByAmount() {
ts.addProtein(10);
assertEquals(10, ts.getTotal());
}
@Test
@Category(GoodCategoryTest.class)
public void whenRemovingProteinTotalRemainsZero() {
ts.removeProtein(5);
assertEquals(0, ts.getTotal());
}
@Test(expected=InvalidGoalException.class)
@Category(GoodCategoryTest.class)
public void testExceptionThrow() throws InvalidGoalException {
ts.setGoal(-5);
}
@Rule
public Timeout timeout = new Timeout(20);
@Test
public void badTest() throws InvalidGoalException {
for(int i=0; i < 1000000000; i++) {
ts.setGoal(1);
}
}
}
当前只有一个BadTest用例会超时,为了演示这个Timtout是作用在全部的测试方法下,我把这个10000000循环代码拷贝到testExceptionThrow()这个测试代码中,看看这个测试方法会不会也运行失败,期待结果是要失败。
如果对其他规则感兴趣,可以去看看官方文档介绍:https://github.com/junit-team/junit4/wiki/Rules
例如这段代码
public class DigitalAssetManagerTest {
@Rule
public final TemporaryFolder tempFolder = new TemporaryFolder();
@Rule
public final ExpectedException exception = ExpectedException.none();
@Test
public void countsAssets() throws IOException {
File icon = tempFolder.newFile("icon.png");
File assets = tempFolder.newFolder("assets");
createAssets(assets, 3);
DigitalAssetManager dam = new DigitalAssetManager(icon, assets);
assertEquals(3, dam.getAssetCount());
}
private void createAssets(File assets, int numberOfAssets) throws IOException {
for (int index = 0; index < numberOfAssets; index++) {
File asset = new File(assets, String.format("asset-%d.mpg", index));
Assert.assertTrue("Asset couldn't be created.", asset.createNewFile());
}
}
@Test
public void throwsIllegalArgumentExceptionIfIconIsNull() {
exception.expect(IllegalArgumentException.class);
exception.expectMessage("Icon is null, not a file, or doesn't exist.");
new DigitalAssetManager(null, null);
}
}