Java 如何在Eclipse中运行通用参数化JUnit测试?

Java 如何在Eclipse中运行通用参数化JUnit测试?,java,eclipse,generics,junit,parameterized,Java,Eclipse,Generics,Junit,Parameterized,为了避免简单集成测试中的大量冗余测试类,我想创建一个参数化的通用测试类,如以下示例所示: @RunWith(Parameterized.class) public class MovementTest<V extends Vehicle, T extends Track<V>> { private final V testVehicle; private final T testTrack; public MovementTest(V veh

为了避免简单集成测试中的大量冗余测试类,我想创建一个参数化的通用测试类,如以下示例所示:

@RunWith(Parameterized.class)
public class MovementTest<V extends Vehicle, T extends Track<V>> {

    private final V testVehicle;

    private final T testTrack;

    public MovementTest(V vehicle, T track){
        testVehicle = vehicle;
        testTrack = track;
    }

    @Test
    public void testMovement(){
        testVehicle.moveAlong(testTrack);
    }

    @Parameters
    public static Iterable<Object[]> provideTestExamples(){
        Object[][] params = {
            { new Car(), new Highway() },
            { new Train(), new RailRoadTrack() }
        };
        return Arrays.asList(params);
    }
}

public interface Vehicle {
    void moveAlong(Track t);
}

public interface Track<E extends Vehicle> { }    

public class Train implements Vehicle {
    @Override
    public void moveAlong(Track t) {}
}

public class RailRoadTrack implements Track<Train> {}

public class Car implements Vehicle {
    @Override
    public void moveAlong(Track t) { }
}

public class Highway implements Track<Car> {}    
@RunWith(参数化的.class)
公共类移动测试{
私人最终V测试车辆;
私人最终测试跑道;
公共交通测试(V型车辆,T型轨道){
测试车辆=车辆;
测试轨道=轨道;
}
@试验
公共运动{
测试车辆。沿(测试轨道)移动;
}
@参数
公共静态Iterable provideTestExamples(){
对象[][]参数={
{新车(),新公路()},
{新火车(),新轨道()}
};
返回数组.asList(params);
}
}
公共接口车辆{
沿轨道移动(t轨道);
}
公共接口磁道{}
公车{
@凌驾
公共空间沿(轨道t){}
}
公共类RailRoadTrack实现轨道{}
公车{
@凌驾
公共空间沿(轨道t){}
}
公共级公路实施轨道{}
不幸的是,这个测试类是不可运行的。是否有一种简洁的方法来实现类似的功能?

\1 您可以使用JUnit的参数化运行程序。其工作原理如下:

@RunWith(Parameterized.class)
public class ParametrizedTest {

    private final String text;
    private final int number;

    public ParametrizedTest(String text, int number) {
        this.text = text;
        this.number = number;
    }

    @Test
    public void shouldContainNumber() {
        assertTrue(text.contains(String.valueOf(number)));
    }

    @Parameterized.Parameters
    public static Iterable<Object[]> params() {
        return Arrays.asList(
                new Object[][]{
                        {"test string 1", 1},
                        {"test string 2", 2}
                }
        );
    }
}
请注意,提供参数的方法的名称必须适合测试名称。此解决方案似乎更好,因为(不仅如此)您在执行后获得了更好的测试名称:

[OK]JUnitParams。[0]测试字符串1,1(shouldContainNumber)

[OK]JUnitParams。[1]测试字符串2,2(shouldContainNumber)

更多关于为什么更好的综合列表可在项目现场找到:

  • 更显式-参数在测试方法参数中,而不是类字段中
  • 代码更少-您不需要构造函数来设置参数
  • 可以在一个类中混合使用参数化方法和非参数化方法
  • 参数可以作为CSV字符串或从参数提供程序类传递
  • 参数提供程序类可以有任意多个提供方法的参数,以便可以对不同的情况进行分组
  • 您可以有一个提供参数的测试方法(不再有外部类或静态)
  • 您可以在IDE中看到实际的参数值(在JUnit的ParameterSid中,只有连续数个参数)

我刚刚解决了一个类似的问题,一个具有复杂参数(对象和对象列表的组合)的参数化测试,我的帮助搜索将我发送到这里

问题中的代码和答案中的代码都应该大致有效。考虑到对象[][]将包含任何内容,使用简单类型的示例提供了足够的信息。唯一可能出现的问题是正确声明复杂类型


我不是用Eclipse运行测试,而是直接用Maven运行测试。

有stacktrace、log之类的吗?您有Object[][]参数,但正在创建新的Object[]@Gaskoin修复了它。此外,Eclipse没有提供运行此测试类的选项,因此没有stacktrace。Eclipse JUnit运行程序将针对类型擦除字节码运行,因此MovementTest是否具有泛型类型参数并不重要。您使用的是相对较新的eclipse版本吗?JUnit4是否在项目路径上?我对EclipseLuna中的参数化测试没有问题,即使是带有泛型类型参数的测试。@KenKoster我尝试了Helios和Luna,结果都是一样的。但事实证明:我太习惯于让JUnit运行配置临时可执行文件,因为IDE通常会自动创建它们。我忽略的是我可以手动创建运行配置。瞧,问题解决了。无论如何,谢谢。是的,这是一个非常基本的参数化测试,我们正在大量使用它。然而,这并不能满足我在特定情况下的需求。这里的重点是“通用”,我明天会去图书馆看看。乍一看很有希望。非常感谢。
@RunWith(JUnitParamsRunner.class)
public class JUnitParamsTest{

    @Test
    @Parameters
    public void shouldContainNumber(String text, int number) {
        assertTrue(text.contains(String.valueOf(number)));
    }

    public Object[] parametersForShouldContainNumber() {
        return $(
                $("test string 1", 1),
                $("test string 2", 2)
        );
    }
}