JUnit4 fail () здесь, но где pass ()?



есть fail() метод в библиотеке JUnit4. Мне это нравится, но испытываю недостаток pass() метод, который отсутствует в библиотеке. Почему это так?



я узнал, что я могу использовать assertTrue(true) вместо этого, но все еще выглядит нелогично.



@Test
public void testSetterForeignWord(){
try {
card.setForeignWord("");
fail();
} catch (IncorrectArgumentForSetter ex){
}

// assertTrue(true);
}
539   6  

6 ответов:

пока тест не выдает исключение, он проходит, если ваш @Test аннотация указывает ожидаемое исключение. Я полагаю, что pass() может бросить специальное исключение, которое JUnit всегда интерпретирует как прохождение, чтобы закоротить тест, но это будет идти вразрез с обычным дизайном тестов (т. е. предполагать успех и терпеть неудачу только в том случае, если утверждение терпит неудачу) и, если люди поняли, что предпочтительнее использовать pass(), это значительно замедлит большой набор прохождения тесты (из-за накладных расходов на создание исключений). Неудачные тесты не должны быть нормой, так что это не имеет большого значения, если у них есть эти накладные расходы.

обратите внимание, что ваш пример может быть переписан следующим образом:

@Test(expected=IncorrectArgumentForSetter.class)
public void testSetterForeignWord("") throws Exception {
  card.setForeignWord("");
}

кроме того, вы должны отдать предпочтение использованию стандартных исключений Java. Ваш IncorrectArgumentForSetter наверное, должен быть IllegalArgumentException.

вызов return заявление в любое время ваш тест завершен и прошел.

Я думаю, что этот вопрос нуждается в обновленном ответе, так как большинство ответов здесь довольно устарели.

во-первых, на вопрос ОП:

Я думаю, что его довольно хорошо принято, что введение концепции "ожидаемого исключения" в JUnit было плохим шагом, так как это исключение может быть поднято в любом месте, и оно пройдет тест. Это работает, если вы бросаете (и утверждаете) очень специфические для домена исключения, но я только бросаю такие исключения, когда работаю в коде, который должен быть абсолютно безупречным, --большинство API будут просто выбрасывать встроенные исключения, такие как IllegalArgumentException или IllegalStateException. Если два вызова, которые вы делаете, могут потенциально вызвать эти исключения, то @ExpectedException аннотация будет зеленый бар ваш тест, даже если его неправильная строка, которая бросает исключение!

для этой ситуации я написал класс, который я уверен, что многие другие здесь написали, это assertThrows способ:

public class Exceptions {
    private Exceptions(){}

    public static void assertThrows(Class<? extends Exception> expectedException, Runnable actionThatShouldThrow){
        try{
            actionThatShouldThrow.run();
            fail("expected action to throw " + expectedException.getSimpleName() + " but it did not.");
        }
        catch(Exception e){
            if ( ! expectedException.isInstance(e)) {
                throw e;
            }
        }
    }
}

этот метод просто возвращается, если создается исключение, позволяющее выполнять дальнейшие утверждения/проверки в тесте.

с синтаксисом Java 8 ваш тест выглядит очень красиво. Ниже приведен один из самых простых тестов на нашей модели, которая использует метод:

@Test
public void when_input_lower_bound_is_greater_than_upper_bound_axis_should_throw_illegal_arg() {
    //setup
    AxisRange range = new AxisRange(0,100);

    //act
    Runnable act = () -> range.setLowerBound(200);

    //assert
    assertThrows(IllegalArgumentException.class, act);
}

эти тесты немного шаткие, потому что шаг" act " на самом деле не выполняет никаких действий, но я думаю, что смысл все еще довольно ясен.

есть также крошечная маленькая библиотека на maven под названием catch-exception что использует синтаксис в стиле mockito, чтобы убедиться, что исключения выбрасываются. Это выглядит красиво, но я не поклонник динамических прокси. Тем не менее, есть синтаксис настолько гладкий, что он остается заманчивым:

// given: an empty list
List myList = new ArrayList();

// when: we try to get the first element of the list
// then: catch the exception if any is thrown 
catchException(myList).get(1);

// then: we expect an IndexOutOfBoundsException
assert caughtException() instanceof IndexOutOfBoundsException;

наконец, для ситуации, с которой я столкнулся, чтобы добраться до этой темы, есть способ игнорировать тесты, Если некоторые conidition встретились.

прямо сейчас я работаю над тем, чтобы некоторые DLL вызывались через Java native-library-loading-library под названием JNA, но наш сервер сборки в Ubuntu. Мне нравится пытаться управлять такого рода развитием с помощью тестов JUnit, хотя они на данный момент далеки от "единиц". То, что я хочу сделать, это запустить тест, если я нахожусь на локальной машине, но игнорировать тест, если мы находимся на ubuntu. JUnit 4 имеет положение для этого, называется Assume:

@Test
public void when_asking_JNA_to_load_a_dll() throws URISyntaxException {
    //this line will cause the test to be branded as "ignored" when "isCircleCI" 
    //(the machine running ubuntu is running this test) is true.
    Assume.assumeFalse(BootstrappingUtilities.isCircleCI());
    //an ignored test will typically result in some qualifier being put on the results, 
    //but will also not typically prevent a green-ton most platforms. 

    //setup
    URL url = DLLTestFixture.class.getResource("USERDLL.dll");
    String path = url.toURI().getPath();
    path = path.substring(0, path.lastIndexOf("/"));

    //act
    NativeLibrary.addSearchPath("USERDLL", path);
    Object dll = Native.loadLibrary("USERDLL", NativeCallbacks.EmptyInterface.class);

    //assert
    assertThat(dll).isNotNull();
}

искал pass метод для JUnit, так что я мог бы закоротить некоторые тесты, которые не были применимы в некоторых сценариях (есть интеграционные тесты, а не чистые модульные тесты). Так что жаль, что его там нет.

к счастью, есть способ, чтобы тест игнорировался условно, что на самом деле подходит еще лучше в моем случае с помощью assumeTrue способ:

предположим.assumeTrue (isTestApplicable);

Так вот тест быть выполнена только при isTestApplicable правда, проверить, в противном случае будут игнорироваться.

нет необходимости в методе pass, потому что при отсутствии AssertionFailedException выбрасывается из тестового кода модульный тестовый случай пройдет.

метод fail () фактически вызывает AssertionFailedException для сбоя testCase, если управление доходит до этой точки.

Я думаю, что этот вопрос является результатом небольшого недопонимания процесса выполнения теста. В JUnit (и других инструментах тестирования) результаты подсчитываются для каждого метода, а не для вызова assert. Там нет счетчика, который отслеживает, сколько прошло / не прошло .

JUnit в выполнении каждого тестового метода в отдельности. Если метод возвращается успешно, то тест регистрируется как "пройденный". Если возникает исключение, то тест регистрируется как"failed". В последнем случае два ней возможны: 1) Вывод исключение утверждения, 2) Любой другой вид исключения. Статус будет " failed "в первом случае, и" error " во втором случае.

на Assert класс многие методы стенографии доступны для создания исключений утверждений. Другими словами,Assert - это уровень абстракции над исключениями JUnit.

например, это исходный код assertEquals on GitHub:

/**
 * Asserts that two Strings are equal.
 */
static public void assertEquals(String message, String expected, String actual) {
    if (expected == null && actual == null) {
        return;
    }
    if (expected != null && expected.equals(actual)) {
        return;
    }
    String cleanMessage = message == null ? "" : message;
    throw new ComparisonFailure(cleanMessage, expected, actual);
}

как вы можете видите ли, в случае равенства ничего не происходит, иначе будет выброшено исключение.

так:

assertEqual("Oh!", "Some string", "Another string!");

просто бросает!--7--> исключение, которое будет поймано JUnit, и

assertEqual("Oh?", "Same string", "Same string");

ничего не делает.

в общем, что-то вроде pass() не будет никакого смысла, потому что он ничего не сделал.

Comments

    Ничего не найдено.