比较枚举时简化测试

Simplify Test while comparing enums

我有一些测试代码如下所示:

@Test
  public void testEnums_AB() {
    // arrange + act
    var enums_1 = Arrays.stream(enumsA.values()).map(Enum::name).collect(Collectors.toSet());
    var enums_2 = Arrays.stream(enumsB.values()).map(Enum::name).collect(Collectors.toSet());

    // assert
    Assertions.assertEquals(enums_1, enums_2);
  }

  @Test
  public void testEnums_CD() {
    // arrange + act
    var enums_3 = Arrays.stream(enumsC.values()).map(Enum::name).collect(Collectors.toSet());
    var enums_4 = Arrays.stream(enumsD.values()).map(Enum::name).collect(Collectors.toSet());

    // assert
    Assertions.assertEquals(enums_3, enums_4);
  }

...等等。

我正在考虑如何简化模式,使逻辑只有一次,例如:

@ParameterizedTest(name = "{index} => enum1={0},enum2={1}")
  @MethodSource("parametersProvider")
  public void testEnum(enum enum1, enum enum2) {
    // arrange + act
    var enumsBlah = Arrays.stream(enum1.values()).map(Enum::name).collect(Collectors.toSet());
    var enumsFoo = Arrays.stream(enum2.values()).map(Enum::name).collect(Collectors.toSet());

    // assert
    Assertions.assertEquals(enumsBlah, enumsFoo);
  }

但是(当然)这个例子甚至是不可编译的。

有没有人知道如何避免这些枚举检查的重复结构?

你的线路

var enums_1 = Arrays.stream(enumsA.values()).map(Enum::name).collect(Collectors.toSet());

应该使用一种方法。假设您有一个名为 testifyEnum 的方法,它将获取一个 enum 参数并计算您赋值的右侧,您只需要做:

var enums_1 = testifyEnum(enumsA);

因此您的代码将如下所示:

@Test
  public void testEnums_AB() {
    // arrange + act
    var enums_1 = testifyEnum(enumsA);
    var enums_2 = testifyEnum(enumsB);

    // assert
    Assertions.assertEquals(enums_1, enums_2);
  }

  @Test
  public void testEnums_CD() {
    // arrange + act
    var enums_3 = testifyEnum(enumsC);
    var enums_4 = testifyEnum(enumsD);

    // assert
    Assertions.assertEquals(enums_3, enums_4);
  }

您可以这样使用 getEnumConstants

import java.util.Arrays;
import java.util.stream.Collectors;

public class Test {
    public static void main(String[] args) {
        testEnum(TestEnum.class, AnotherTestEnum.class);
    }

    private static <T extends Enum<T>, T2 extends Enum<T2>> void testEnum(Class<T> enums1Class, Class<T2> enums2Class) {
        var enums1 = Arrays.stream(enums1Class.getEnumConstants()).map(Enum::name).collect(Collectors.toSet());
        var enums2 = Arrays.stream(enums2Class.getEnumConstants()).map(Enum::name).collect(Collectors.toSet());

        // compare here
    }

    private enum TestEnum {
        A, B
    }

    private enum AnotherTestEnum {
        A, B
    }
}

作为 JUnit 5 测试:

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;

import java.util.Arrays;
import java.util.stream.Collectors;

class EnumTest {
    private static Object[][] parametersProvider() {
        return new Object[][]{
                {TestEnum.class, AnotherTestEnum.class}
        };
    }

    @ParameterizedTest(name = "{index} => enum1={0}, enum2={1}")
    @MethodSource("parametersProvider")
    <T extends Enum<T>, T2 extends Enum<T2>> void testEnum(Class<T> enums1Class, Class<T2> enums2Class) {
        var enums1 = Arrays.stream(enums1Class.getEnumConstants()).map(Enum::name).collect(Collectors.toSet());
        var enums2 = Arrays.stream(enums2Class.getEnumConstants()).map(Enum::name).collect(Collectors.toSet());

        Assertions.assertEquals(enums1, enums2);
    }

    private enum TestEnum {
        A, B
    }

    private enum AnotherTestEnum {
        A, B
    }
}