JUnit4中的Rule注解

2020-01-04  本文已影响0人  剑过不留名

@Rule

注意所有声明的rule对象前面都是public final;
以下是Junit4中已经实现的rule:

1,TemporaryFolder

TemporaryFolder可以创建文件或文件夹,测试完成后自动删除

@Rule
public final TemporaryFolder folder = new TemporaryFolder();

@Test
public void testUsingTempFolder() throws IOException {
    File createdFile = folder.newFile("myfile.txt");
    File createdFolder = folder.newFolder("subfolder");
    // ...
}

2,ExternalResource

测试前创建Resource,并保证测试后自动销毁Resouce

Server myServer = new Server();
  
@Rule
public final ExternalResource resource = new ExternalResource() {
    @Override
    protected void before() throws Throwable {
        myServer.connect();
    };

    @Override
    protected void after() {
        myServer.disconnect();
    };
};
  
@Test
public void testFoo() {
    new Client().run(myServer);
}

3,ErrorCollector

抛出异常后继续运行,可以用来收集所有的异常,最后一起显示

@Rule
public final ErrorCollector collector = new ErrorCollector();

@Test
public void example() {
    collector.addError(new Throwable("first thing went wrong"));
    collector.addError(new Throwable("second thing went wrong"));
}

4,Verifier

@Test通过后并且verify通过才会认为测试通过。

private static String sequence="";

@Rule
public final Verifier collector = new Verifier() {
    @Override
    protected void verify() {
        assertEquals("test verify ",sequence);
    }
};

@Test
public void example() {
    sequence = "test ";
    // 由于不能经过verify,所以报错
}

@Test
public void verifierRunsAfterTest() {
    sequence = "test verify ";
}

5,TestWatcher

可以监控测试的每一个阶段

private static String watchedLog;

// 测试完毕后,输出所有的测试结果
@AfterClass
public static void log(){
    System.out.println(watchedLog);
}

@Rule
public final TestRule watchman = new TestWatcher() {
    @Override
    public Statement apply(Statement base, Description description) {
        return super.apply(base, description);
    }

    @Override
    protected void succeeded(Description description) {
        watchedLog += description.getDisplayName() + " " + "success!\n";
    }

    @Override
    protected void failed(Throwable e, Description description) {
        watchedLog += description.getDisplayName() + " " + e.getClass().getSimpleName() + "\n";
    }

    @Override
    protected void skipped(AssumptionViolatedException e, Description description) {
        watchedLog += description.getDisplayName() + " " + e.getClass().getSimpleName() + "\n";
    }

    @Override
    protected void starting(Description description) {
        super.starting(description);
    }

    @Override
    protected void finished(Description description) {
        super.finished(description);
    }
};

@Test
public void fails() {
    fail();
}

@Test
public void succeeds() {
}

6,TestName

可以获得测试方法的名称

@Rule
public final TestName name = new TestName();

@Test
public void testA() {
    assertEquals("testA", name.getMethodName());
}

7,Timeout

设置测试类中所有测试的超时时间

@Rule
public final TestRule globalTimeout = Timeout.millis(20);
  
@Test
public void testInfiniteLoop1() {
    for(;;) {}
}
  
@Test
public void testInfiniteLoop2() {
    for(;;) {}
}

8,ExpectedException

指定测试case中抛出的异常以及异常信息

@Rule
public final ExpectedException thrown = ExpectedException.none();

@Test
public void throwsNullPointerException() {
    thrown.expect(NullPointerException.class);
    throw new NullPointerException();
}

@Test
public void throwsNullPointerExceptionWithMessage() {
    thrown.expect(NullPointerException.class);
    thrown.expectMessage("happened?");
    thrown.expectMessage(startsWith("What"));
    throw new NullPointerException("What happened?");
}

9,ChainRule

指定Rule的顺序

public final TestWatcher testWatcher1=new TestWatcher() {
    @Override
    protected void starting(Description description) {
        System.out.println("watcher1 start");
    }

    @Override
    protected void finished(Description description) {
        System.out.println("watcher1 finish");
    }
};
public final TestWatcher testWatcher2=new TestWatcher() {
    @Override
    protected void starting(Description description) {
        System.out.println("watcher2 start");
    }

    @Override
    protected void finished(Description description) {
        System.out.println("watcher2 finish");
    }
};
public final TestWatcher testWatcher3=new TestWatcher() {
    @Override
    protected void starting(Description description) {
        System.out.println("watcher3 start");
    }

    @Override
    protected void finished(Description description) {
        System.out.println("watcher3 finish");
    }
};

@Rule
public final TestRule chain = RuleChain
    .outerRule(testWatcher1)
    .around(testWatcher2)
    .around(testWatcher3);

@Test
public void example() {
    assertTrue(true);
}

10,Custom Rules

用户自定义Rule,需要实现TestRule接口,重写apply方法

@ClassRule

ParentRunner的所有子类,包括BlockJUnit4ClassRunnerSuite都支持@ClassRule

@ClassRule创建的Rule会应用到整个类

@ClassRule修饰对象的限定符是public static final

@RunWith(Suite.class)
@SuiteClasses({A.class, B.class, C.class})
public class UsesExternalResource {
  public static final Server myServer = new Server();

  @ClassRule
  public static final ExternalResource resource = new ExternalResource() {
    @Override
    protected void before() throws Throwable {
      myServer.connect();
    };

    @Override
    protected void after() {
      myServer.disconnect();
    };
  };
}
上一篇下一篇

猜你喜欢

热点阅读