JUnit領域中最有用的創新之一是Rule。 我在這里寫了有關規則的文章 。 我在這里寫了有關JUnit規則的用例 。 規則很棒。 借助JUnit 4.9,它們變得更好。
您可以將規則視為將測試的設置和拆卸封裝在一個類中而不是兩個方法中的一種方法。 但是規則也是一種修改執行測試方式的方法。 您可以多次運行測試,而不是一次。 或在二十個不同的線程中。 有趣的是,只有單個測試規則。 因此,如果您要堅持進行設置和拆卸的比較, 那么@Before和@After則在Rule中沒有等效的@BeforeClass和@AfterClass 。
現在情況已經改變。 現在,您可以標注類型TestRule的公共靜態字段與@ClassRule,它會表現就像是一整個測試類,而不是一個單一的測試定義的規則。 因此,對于需要為所有測試設置一次而不是為每個測試設置一次的東西而言,它是完美的選擇。 讓我們來看一個例子。
規則的實現可能如下所示:
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;public class LoggingRule implements TestRule {public class LoggingStatement extends Statement {private final Statement statement;public LoggingStatement(Statement aStatement, String aName) {statement = aStatement;}@Overridepublic void evaluate() throws Throwable {System.out.println("before: " + name);statement.evaluate();System.out.println("after: " + name);}}private final String name;public LoggingRule(String aName) {name = aName;}@Overridepublic Statement apply(Statement statement, Description description) {System.out.println("apply: " + name);return new LoggingStatement(statement, name);}}
大多數實現將由兩部分組成: TestRule接口的實現和Statement接口的實現。
TestRule替換了以前不推薦使用的MethodRule接口。 這是因為新接口同時支持類級別和方法級別的Rule,因此必須進行一些更改。 TestRule有一個應用apply方法,該方法接受一條Statement并返回一條Statement 。 在執行Rule范圍內的任何測試之前,將調用此方法。 傳入的Statement實際上是可能執行的測試。 這里需要注意兩件事:如果您的Rule與@ClassRule批注一起使用,則Statement可能并且將代表多個測試; 調用apply并不意味著Statement實際上會被執行。 由于您的規則返回的任何內容都可能傳遞給其他規則,因此在實際執行所包含的測試之前,可能會以各種方式對語句進行處理。 apply方法中要做的典型事情是將Statement包裹在一個新的Statement中 ,它將執行您所需的邏輯。
Statement接口具有單個方法評估 ,在正常情況下應執行一個測試或一堆測試。 因此,如果采用上述典型方法,則需要對包含的Statement 進行一些設置調用評估 ,并進行拆卸。 在上面提供的示例中,我在控制臺上打印內容,以便可以看到以什么順序調用內容。 該語句還傳遞了一個描述 ,其中包含有關測試的有用的元信息。 它包含名稱,定義測試的類,方法名稱并提供注釋。 因此,您的“規則/聲明”可以根據其操作所依據的測試方法來微調其行為。
使用此規則的測試類可能如下所示:
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;public class RuleTest {@ClassRulepublic static LoggingRule classRule = new LoggingRule("classrule");@Rulepublic static LoggingRule rule = new LoggingRule("rule");@Testpublic void testSomething() {System.out.println("In TestSomething");assertTrue(true);}@Testpublic void testSomethingElse() {System.out.println("In TestSomethingElse");assertTrue(true);}
}
對JUnit4.8規則的唯一更改是@ClassRule批注的存在。 請注意,同一類與@ClassRule和@Rule批注一起使用。
執行后,測試類的輸出如下所示:
apply: classrule
before: classrule
apply: rule
before: rule
In TestSomething
after: rule
apply: rule
before: rule
In TestSomethingElse
after: rule
after: classrule
如您所見,首先將應用類級別的Rule并評估結果Statement 。 僅作為評估的一部分,才應用方法級別的“規則”并評估結果“ 語句” ,每次測試一次。
提醒您一句:小心在“規則”中使用正確的修飾符。 它們必須是公共的,并且類級別的規則必須是靜態的。 取決于您做錯了什么(以及您在什么環境中工作),導致的錯誤可能并不完全有用。 這被認為是一個錯誤,并且正在修復。
參考:來自Schauderhaft博客的JCG合作伙伴 Jens Schauder的 JUnit 4.9(測試版3)中的規則 。
相關文章 :
- Java工具:源代碼優化和分析
- 框架使開發人員愚蠢嗎?
- 每個程序員都應該知道的事情
- JDK中的設計模式
- Java最佳實踐
翻譯自: https://www.javacodegeeks.com/2011/09/rules-in-junit-49-beta-3.html