簡體   English   中英

在任何測試步驟之前,在每個JUnit中調用一個私有方法

[英]Calling a private method inside every JUnit before any test steps

我想知道在編寫JUnit測試時以下內容之間是否存在技術上的區別:

選項1:定義一個設置方法,即使用@Before注釋,以在運行任何@Test方法之前初始化測試治具的狀態。

選項2:定義一個私有方法-只是一個普通的老式私有方法,沒有任何注釋-進行相同的初始化,並將每個@Test方法的第一行稱為對此方法的調用。 (忽略有人在每次測試中忘記調用該方法的可能性。我在尋找技術差異,而不是人為因素)

選項2的示例:

public class MyTest {

    private void runSetupLogic() {
        // whatever @Before method would have done
    }

    @Test
    public void testMethod1() {
        runSetupLogic();
        // test logic
    }

    @Test
    public void testMethod2() {
        runSetupLogic();
        // test logic
    }
}

我不相信。
但是,如果您要實現另一個函數,例如tearDown() ,則該函數實際上將用作@After方法,我認為您最好將它們用於可讀性,以使其他協作者甚至您自己受益。

使用@Before@After注釋的好處是,它們避免在每次單元測試開始時都必須調用方法,這是為了節省您的額外維護。 如果由於某種原因您忘記將調用添加到setUp()和/或tearDown()方法中,誰知道會出問題。

當然,這是在每次測試之前都需要完全相同的設置。 如果您打算為完全不同的單元測試設置完全不同的設置,那么也許您應該查看所測試類的功能,並問自己是否可以進一步模塊化。

它們實際上並不完全相同 ,但是無論從哪方面來看,任何一種方法都應該是正確的。 但是,如果您對技術分析感興趣,那么我對Github上當前的JUnit 4代碼的理解就會有些不穩定:

這是當您使用@Before使用默認的JUnit 4運行程序src / main / java / org / junit / runners / BlockJUnit4ClassRunner.java時,似乎正在運行的實際代碼:

/**
 * Returns a {@link Statement}: run all non-overridden {@code @Before}
 * methods on this class and superclasses before running {@code next}; if
 * any throws an Exception, stop execution and pass the exception on.
 */
protected Statement withBefores(FrameworkMethod method, Object target,
        Statement statement) {
    List<FrameworkMethod> befores = getTestClass().getAnnotatedMethods(
            Before.class);
    return befores.isEmpty() ? statement : new RunBefores(statement,
            befores, target);
}

上面在src / main / java / org / junit / internal / runners / statements / RunBefores.java中調用RunBefores

public class RunBefores extends Statement {
    private final Statement next;

    private final Object target;

    private final List<FrameworkMethod> befores;

    public RunBefores(Statement next, List<FrameworkMethod> befores, Object target) {
        this.next = next;
        this.befores = befores;
        this.target = target;
    }

    @Override
    public void evaluate() throws Throwable {
        for (FrameworkMethod before : befores) {
            before.invokeExplosively(target);
        }
        next.evaluate();
    }

invokeExplosively方法定義位於src / main / java / org / junit / runners / model / FrameworkMethod.java中

public Object invokeExplosively(final Object target, final Object... params)
        throws Throwable {
    return new ReflectiveCallable() {
        @Override
        protected Object runReflectiveCall() throws Throwable {
            return method.invoke(target, params);
        }
    }.run();
}

這似乎使用反射來調用@Before注釋的方法。

無論如何,希望這個答案是正確的,但是我不確定。 如果任何人有任何更正,我可以從注釋中對其進行編輯。 順便說一句,這里提供@Before注釋的Javadoc: http : @Before

好處來自於報告。

在您的方法中:runSetupLogic()

從測試開始運行時,將在測試內報告。 不作為設置的一部分,也不作為初始化的一部分。

如果安裝方法失敗,您將准確了解失敗的原因...安裝與測試。

使用before方法,您可以將測試失敗與設置失敗隔離開來,並使報告解決方案也可以知道。

暫無
暫無

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

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