簡體   English   中英

如何使用JUnit中的規則訪問測試類的字段

[英]How to access the fields of a test class with in an Rule in JUnit

我想編寫一個JUnit @Rule(版本4.10)來設置一些對象(實體管理器),並通過將它“注入”變量使它們在測試中可用。

像這樣的東西:

public class MyTestClass() {

  @Rule
  MyEntityManagerInjectRule = new MyEntityManagerInjectRule():

  //MyEntityManagerInjectRule "inject" the entity manager
  EntityManger em;

  @Test...
}

問題是我不知道如何在MyEntityManagerInjectRule(擴展TestRule)中獲取MyTestClass的當前實例,因為它只有一個方法。 Statement apply(Statement base, Description description);

在Description內,只有MyTestClass類,但沒有用於測試的實例。

另一種方法是使用org.junit.rules.MethodRule,但不推薦使用。 之前和之后不足以完成此任務,因為那時我需要將代碼復制到測試中,並且它們或多或少都被棄用了。 (參見Block4JClassRunner.withBefores / withAfters)。

所以我的問題是如何在不使用棄用的東西的情況下訪問測試類實例。

實現這一目標的正確方法是使你的規則實現org.junit.rules.MethodRule (而不是TestRule )。 MethodRule接口的apply()方法有一個target參數,它保存對測試類當前實例引用 (當然,每次執行一個方法時它都是一個不同的實例)。

示例MethodRule

public class ExampleMethodRule implements MethodRule {

    @Override
    public Statement apply(final Statement base,
                                         FrameworkMethod method, Object target) {
        System.out.println("ExampleMethodRule#apply()" +
                           "\n\t base: " + base +
                           "\n\t method (current test method): " + method +
                           "\n\t target (current test class instance): "+target);

        return new Statement() {
            @Override
            public void evaluate() throws Throwable {
                System.out.println("->before evaluate()");
                try {
                    base.evaluate();
                } finally {
                    System.out.println("->after evaluate()");
                }
            }
        };
    }
}

使用@Rule示例測試類

public class ExampleTest {

    @Rule
    public ExampleMethodRule exampleMethodRule = new ExampleMethodRule();

    @BeforeClass
    public static void beforeClass() {
        System.out.println("@BeforeClass");
    }
    @AfterClass
    public static void afterClass() {
        System.out.println("@AfterClass");
    }

    @Before
    public void before() {
        System.out.println("@Before");
    }
    @After
    public void after() {
        System.out.println("@After");
    }

    @Test
    public void aa() {
        System.out.println("method aa()");
    }
    @Test
    public void bb() {
        System.out.println("method bb()");
    }

}

怎么樣:

public class MyTestClass() {
  @Rule
  public TestRule MyEntityManagerInjectRule =
         new MyEntityManagerInjectRule(this); // pass instance to constructor

  //MyEntityManagerInjectRule "inject" the entity manager
  EntityManger em;

  @Test...
}

只需將測試類實例添加到@Rule的構造函數中。 請注意分配順序。

有一種不同的方法:規則提供EntityManager而不是注入它。

public class MyTestClass() {
  @Rule
  public MyEntityManagerRule rule = new MyEntityManagerRule();

  @Test
  public void firstTest() {
     doSomethingWith(rule.getEntityManager());
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM