Как подключить DataPoint с помощью теории?

@DataPoints public static final Integer[] input1={1,2};
@Theory
@Test
public void test1(int input1){

}

@DataPoints public static final Integer[] input2={3,4};
@Theory
@Test
public void test2(int input2 ){

}

Я хочу, чтобы test1 работал с вводом набора данных1 - {1,2}, а test2 запускался с input2 - {3,4}. Но в настоящее время каждый тест выполняется как с наборами данных {1,2,3,4}. Как привязать определенные @DataPoints к определенным @Theorys

Ответы

Ответ 1

DataPoints применяются к классу. Если у вас есть метод @Theory, который принимает int, и у вас есть DataPoint, который является массивом из int, тогда он будет вызываться с помощью int.

@RunWith(Theories.class)
public class TheoryTest {
    @DataPoint public static int input1 = 45;
    @DataPoint public static int input2 = 46;
    @DataPoints public static String[] inputs = new String[] { "foobar", "barbar" };

    @Theory public void testString1(String input) {
        System.out.println("testString1 input=" + input);
    }

    @Theory public void testString2(String input) {
        System.out.println("testString2 input=" + input);
    }

    @Theory public void test1(int input) {
        System.out.println("test1 input=" + input);
    }

    @Theory public void test2(int input) {
        System.out.println("test2 input=" + input);
    }
}

Это вызывает test1 с 45 и 46 и test2 с 45 и 46. Он вызывает testString1 с "foobar" и "barbar" и testString2 с "foobar" и "barbar".

Если вы действительно хотите использовать разные наборы данных для разных теорий, вы можете обернуть данные в частный класс:

@RunWith(Theories.class)
public class TheoryTest {
    public static class I1 { int i; public I1(int i) { this.i = i;} }
    public static class I2 { int i; public I2(int i) { this.i = i;} }

    @DataPoint public static I1 input1 = new I1(45);
    @DataPoint public static I2 input2 = new I2(46);

    @Theory
    public void test1(I1 input) {
        System.out.println("test1 input=" + input.i);
    }

    @Theory
    public void test2(I2 input) {
        System.out.println("test2 input=" + input.i);
    }
}

Это вызывает test1 с 45 и test2 с 46. Это работает, но, на мой взгляд, это заслоняет код, и это может быть лучшим решением, чтобы просто разбить класс Test на два класса.

Ответ 2

С JUnit 4.12 (не уверен, когда он был введен) можно назвать DataPoints и назначить их параметрам (я узнал его из http://farenda.com/junit/junit-theories-with-datapoints/):

@RunWith(Theories.class)
public class TheoriesAndDataPointsTest {
    @DataPoints("a values")
    public static int[] aValues() {
        return new int[]{1, 2};
    }

    @DataPoints("b values")
    public static int[] bValues() {
        return new int[]{3, 4};
    }

    @Theory
    public void theoryForA(@FromDataPoints("a values") int a) {
        System.out.printf("TheoryForA called with a = %d\n", a);
    }

    @Theory
    public void theoryForB(@FromDataPoints("b values") int a) {
        System.out.printf("TheoryForB called with b = %d\n", a);
    }
}

Вывод:

TheoryForA called with a = 1
TheoryForA called with a = 2
TheoryForB called with b = 3
TheoryForB called with b = 4

Ответ 3

Некоторые из ссылок, которые я видел, говорят об использовании тестов для определенных значений и теорий для проверки поведения. В качестве примера, если у вас есть класс, который имеет методы для добавления и вычитания из атрибута, тест проверяет правильность результата (например, 1 + 3 возвращает 4), тогда как теория может проверить, что для значений данных (x1, y1), (x2, y2), x + yy всегда равно x, x-y + y всегда равно x, x * y/y всегда равно x и т.д. Таким образом, результаты теорий не связаны так сильно с данные. С теориями вы также можете отфильтровать такие случаи, как y == 0; они не считаются ошибкой. Итог: вы можете использовать оба. Хорошая статья: http://web.archive.org/web/20110608210825/http://shareandenjoy.saff.net/tdd-specifications.pdf