Упростить тест при сравнении перечислений - PullRequest
2 голосов
/ 06 ноября 2019

У меня есть некоторый тестовый код, который выглядит следующим образом:

@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);
  }

Но (конечно) этот пример даже не компилируется.

У кого-нибудь есть идея избежать повторяющейся структуры для этих проверок перечисления?

Ответы [ 2 ]

2 голосов
/ 06 ноября 2019

Вы можете использовать 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
    }
}
0 голосов
/ 06 ноября 2019

Ваша строка

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);
  }
...