Подтвердить что ты не робот

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

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

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

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

 // assertTrue(true);
 }
4b9b3361

Ответ 1

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

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

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

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

Ответ 2

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

Ответ 3

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

Во-первых, вопрос OP:

Я думаю, что он довольно хорошо согласился с тем, что введение концепции ожидаемого excepetion в JUnit было плохим шагом, поскольку это исключение можно было бы поднимать где угодно, и оно пройдет тест. Он работает, если вы бросаете (и утверждаете) очень специфичные для домена исключения, но я бросаю только те исключения, когда я работаю над кодом, который должен быть абсолютно безупречным, - почти APIS просто выкинет встроенные исключения, такие как 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;

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

В настоящее время я работаю над получением некоторых DLL, вызванных через библиотеку java-библиотеки, загружаемую через 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();
}

Ответ 4

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

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

Assume.assumeTrue(isTestApplicable);

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

Ответ 5

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

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

Ответ 6

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

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

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

Например, это исходный код assertEquals на 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!");

просто выдает исключение ComparisonFailure, которое будет уловлено JUnit и

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

НИЧЕГО.

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

Ответ 7

Все проходит, и испытания должны пройти...