通用 JUnit 测试

sim*_*ont 3 java generics junit

我有一个抽象的泛型集合类GCollection,以及一个扩展名为GStack.

为了测试实现,我有一个抽象的 JUnit 测试类,我为GCollection我所做的每个实现进行了扩展:

public abstract class GCollectionTest<T extends GCollection<E>, E> {
    private GCollection<? extends Object> collection;
    protected abstract GCollection<T> createInstance();

    @Before
    public void setup() throws Exception {
        collection = createInstance();
    }

    // Tests down here. 
Run Code Online (Sandbox Code Playgroud)

这是这样扩展的:

public class GStackCollectionInterfaceTest<S extends GCollection<E>> {
    protected GDSStack<? extends Object> createInstance() {
        return new GDSStack<String>();
    }
}
Run Code Online (Sandbox Code Playgroud)

我首先使用GStack持有String对象进行测试,然后使用Date对象重新运行测试以确保它适用于不同的对象类型。

@Test
public void testIsEmpty() {
    assertTrue(collection.isEmpty()); // Fresh Stack should hold no objects
    collection.add(new String("Foo")); // Error here.
    assertFalse(collection.isEmpty());
}
Run Code Online (Sandbox Code Playgroud)

给出的错误是:

GCollection 类型中的 add(capture#24-of ? extends Object) 方法不适用于参数 (String)

我对错误的理解是我无法将String对象放入GCollection<T extends GCollection<E>>对象中,但我认为这不是我想要做的。

我究竟做错了什么?

如何在维护尽可能通用的测试的同时解决此错误?

fgb*_*fgb 6

集合的类型是GCollection<? extends Object>。无法向该集合添加任何内容,请参阅:无法向具有通配符泛型类型的 java 集合添加值

子类中不需要通配符或边界,因此您可以简化泛型。就像是:

abstract class GCollectionTest<T> {
    protected Collection<T> collection;

    protected abstract Collection<T> createCollection();
    protected abstract T createObject();

    @Before
    public void setup() throws Exception {
        collection = createCollection();
    }

    @Test
    public void testIsEmpty() {
        assertTrue(collection.isEmpty());
        collection.add(createObject());
        assertFalse(collection.isEmpty());
    }
}

class GStackCollectionInterfaceTest extends GCollectionTest<String> {
    protected GDSStack<String> createCollection() {
        return new GDSStack<String>();
    }

    protected String createObject() {
        return new String("123");
    }
}
Run Code Online (Sandbox Code Playgroud)

由于泛型类型,允许在集合中使用不同的类型,并由编译器检查,因此它实际上不需要测试。我只是想测试不同的容器类型,但你可以创建使用其他子类Date来代替String