[英]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()
共享相同的實現,則可以考慮將實現移至一個公共基類,並為該基類編寫測試。
僅僅因為類共享相同的接口,並不意味着它們的測試需要集中和耦合。
分別為每個實現創建一個測試: QuickListTest
和EfficientMemoryListTest
。
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.