假设我有一个抽象类Pipeline<T>
,其中包含类型T
的某些元素,而一个实现类IntPipeline
则扩展了Pipeline<Integer>
。
abstract class Pipeline<T> {
abstract T getNextItem();
}
class IntPipeline extends Pipeline<Integer> {
Integer getNextItem() {
// generate integer here
return 0;
}
}
现在我要编写一些测试。由于Pipeline
的所有实现都会有类似的测试,因此我想创建一个抽象基类来定义一些标准测试:
abstract class PipelineTest<S, T extends Pipeline<S>> {
private final Class<T> clazz;
protected PipelineTest(Class<T> clazz) {
this.clazz = clazz;
}
abstract T createInstance();
@Test
void canBeSerializedAndDeserialzed() {
var serializer = ...;
T pipeline = createInstance();
var json = serializer.toJson(pipeline);
T deserializedPipeline = serializer.fromJson(json, clazz);
assertEquals(pipeline, deserializedPipeline);
}
}
因此具体测试如下:
class IntPipelineTest extends PipelineTest<Integer, IntPipeline> { // redundant information here
IntPipelineTest() {
super(IntPipeline.class);
}
IntPipeline createInstance() {
return new IntPipeline();
}
}
如您所见,当我创建一个具体的测试时,我需要在那里传递冗余信息。我告诉编译器,我将为类型Integer
的管道创建一个测试。据我了解,这可以从IntPipeline
推论得出。因此,我怀疑仿制药在做一些根本上错误的事情。
那么有什么方法可以重组代码,以便我可以创建测试而无需显式声明Integer
类型?