簡體   English   中英

測試實現相同接口的類的最佳方法

[英]The best way to test classes implementing the same interface

因此,例如,我有一些實現List<T>接口的類。 如何測試它們-它們是否正確實現了這些方法?

現在,我只看到一種方法:

public class MyListImplementationsTest {
    private Collection<List<Integer>> listImplementations;

    @BeforeClass
    public static void setUp() throws Exception {
        listImplementations = Arrays.asList(
            new QuickList<Integer>(), new EfficientMemoryList<Integer>()
        );
    }

    @Test
    public void testIsEmptyAfterCreationEmptyList() {
        // Use forEachList(handler) in order to not iterate
        // the lists manually every time.
        // May be there is no need to do so,
        // because using <<for (item : items)>> instead of
        // iterating using index prevents from OutOfBounds errors
        forEachList(new OnEachListHandler<Integer>() {
            @Override
            public void onEach(List<Integer> list) {
                assertTrue(list.isEmpty());
            }
        });
    }

    private <T> void forEachList(OnEachListHandler<T> handler) {
        for (List<T> each : listImplementations) {
            handler.onEach(each);
        }
    }

    private static interface OnEachListHandler<T> {
        void onEach(List<T> each);
    }
}

但是我認為在每個測試中迭代列表很復雜。

有沒有更優雅的方法來測試在JUnit4實現相同接口的JUnit4

您可以創建一個基本測試,該測試可以測試List<T>類型的任何內容,以及可以創建此類列表的抽象方法。

然后對每個列表類型實施一個測試,以擴展基礎測試。 JUnit將運行基類以及您在擴展中定義的任何測試用例。

abstract class AbstractListTest<T> {
    protected abstract List<T> createList();

    @Test
    public void testIsEmpty() {
        List<T> list = createList();
        assertTrue(list.isEmpty());
    }

    ...more tests...
}

class QuickListTest extends AbstractListTest<QuickList> {
    protected QuickList createList() {
        return new QuickList();
    }
}

JUnit不會運行抽象基類,但它將看到繼承的測試並運行所有測試。 您還可以將新測試添加到QuickListTest或從基類覆蓋這些測試。

基本上,JUnit將采用該類,從整個繼承樹中找到所有公共@Test方法並運行它們。

我將考慮將針對不同列表實現的測試分解為各自的測試用例,以使它們獨立地通過或失敗。

以您的.isEmpty()為例,如果QuickList.isEmpty()EfficientMemoryList.isEmpty()具有不同的實現,即對empty概念的含義不同,則對它們進行獨立測試是有意義的。 當前,如果1個列表實現失敗,但其他通過的testIsEmptyAfterCreationEmptyList將失敗。

否則,如果QuickList.isEmpty()EfficientMemoryList.isEmpty()共享相同的實現,則可以考慮將實現移至一個公共基類,並為該基類編寫測試。

僅僅因為類共享相同的接口,並不意味着它們的測試需要集中和耦合。

分別為每個實現創建一個測試: QuickListTestEfficientMemoryListTest

QuickListTest.java

public class QuickListTest extends ListBase {   
    @Test
    public void shouldBeEmpty() throws Exception {   
        assertThatIsEmpty(new QuickList<Integer>());   
    }    
}

BaseList.java

public abstract class ListBase {    
    protected void assertThatIsEmpty(QuickList<Integer> actual) {
        assertThat(actual).isEmpty();
    }
}

暫無
暫無

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

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