1

我正在为类似于下面的代码编写参数化单元测试,以确保我的测试涵盖所有可能的输入情况并且系统按预期运行。

我想出了 3 种方法,即 testGetAnimalMood1、testGetAnimalMood2、testGetAnimalMood3:

public class Exp {

    enum Animal{
        CAT("Cat is happy"),
        DOG("Dog is sad");

        Animal(String mood){
            this.mood = mood;
        }

        private String mood;

        public String getMood(){
            return this.mood;
        }
    }

    public static String getAnimalsMood(String animal){
        return Animal.valueOf(animal).getMood();
    }
}

public class ExpTest {

    @ParameterizedTest
    @CsvSource({"CAT, Cat is happy", "DOG, Dog is sad"})
    public void testGetAnimalMood1(String animal, String expected){
        String mood = Exp.getAnimalsMood(animal);

        Assertions.assertEquals(expected, mood);
    }

    @ParameterizedTest
    @MethodSource("getAnimalMoodParameters2")
    public void testGetAnimalMood2(String animal, String expected){
        String mood = Exp.getAnimalsMood(animal);

        Assertions.assertEquals(expected, mood);
    }

    public static Stream<Arguments> getAnimalMoodParameters2(){
        return Stream.of(Arguments.of("CAT", "Cat is happy"),Arguments.of("DOG", "Dog is sad"));
    }

    @ParameterizedTest
    @MethodSource("getAnimalMoodParameters3")
    public void testGetAnimalMood3(String animal, String expected){
        String mood = Exp.getAnimalsMood(animal);

        Assertions.assertEquals(expected, mood);
    }

    public static Stream<Arguments> getAnimalMoodParameters3(){
        return Arrays.stream(Exp.Animal.values()).map(e -> Arguments.of(e.name(), e.getMood()));
    }

}

通过使用 MethodSource,testGetAnimalMood2 看起来比 testGetAnimalMood1 更干净。然而,与此同时,比以前更难读取用于测试的值。认为 getAnimalMoodParameters2 方法没有增加多少价值,使用哪个版本更好?

testGetAnimalMood3 看起来更干净,但它有验证我的错误逻辑的潜在危险,因为它使用与代码下的测试类似的方法来获取值。此外,如果我不将值写为字符串,我可能无法捕捉到可能的拼写错误。但是一个反驳的论点是,另一个试图修改此代码的用户可能无法通过查看那些任意字符串来理解行为。

考虑所有这些论点,或者如果你必须添加更多,哪一个是最好的方法?

4

1 回答 1

0

我在编写参数化测试时使用此设置:

@RunWith(Parameterized.class)
public class MyTest {
    @Parameter(0)
    public String animal;
    @Parameter(1)
    public String expected;

    @Parameters
    public static List<String[]> parameters() {
        return Arrays.asList(
            new String[]{"CAT", "Cat is happy"},
            new String[]{"DOG", "Dog is sad"}
        );
    }

    @Test
    public void testGetAnimalMood(){
        String mood = Exp.getAnimalsMood(animal);

        Assertions.assertEquals(expected, mood);
    }
}

@RunWith(Parameterized.class)告诉 JUnit 使用不同的参数运行您的类。

带有注释的静态方法@Parameters是您的方法源。

用注释的两个字段@Parameter告诉 JUnit 应该在哪个索引处选择哪个参数。

其余的应该是自我解释的

于 2019-04-03T13:04:08.723 回答