Как на самом деле используется «сбой» в тестовом примере JUnit?

Ответы:

138

Некоторые случаи, когда я нашел это полезным:

  • отметить незавершенный тест, чтобы он не прошел, и предупреждает вас, пока вы не закончите его
  • убедившись, что выбрано исключение:
try{
  // do stuff...
  fail("Exception not thrown");
}catch(Exception e){
  assertTrue(e.hasSomeFlag());
}

Примечание:

Начиная с JUnit4, существует более элегантный способ проверить возникновение исключения: использовать аннотацию @Test(expected=IndexOutOfBoundsException.class)

Однако это не сработает, если вы также хотите проверить исключение, тогда вам все равно нужно fail().

sleske
источник
5
Рассмотрим это сообщение в блоге об относительных достоинствах аннотации fail по сравнению с ожидаемой: blog.jooq.org/2016/01/20/…
lbalazscs
4
@sleske "если вы также хотите проверить исключение, вам все равно понадобится fail ()" - нет. ExpectedException путь, см github.com/junit-team/junit4/wiki/exception-testing
kraxor
@kraxor: Верно, не знал об этом, когда писал ответ (наверное, тогда еще не было).
sleske
14

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

try{
   bizMethod(badData);
   fail(); // FAIL when no exception is thrown
} catch (BizException e) {
   assert(e.errorCode == THE_ERROR_CODE_U_R_LOOKING_FOR)
}
kartheek
источник
10

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

Что-то вроде следующего псевдокода:

test_addNilThrowsNullPointerException()
{
    try {
        foo.add(NIL);                      // we expect a NullPointerException here
        fail("No NullPointerException");   // cause the test to fail if we reach this            
     } catch (NullNullPointerException e) {
        // OK got the expected exception
    }
}
philant
источник
3
Если вы что-то не проверяете в блоке catch, вы можете использовать аннотацию метода @ExpectedException (NullNullPointerException.class), чтобы объявить, что вы ожидаете исключения (особого типа).
FrVaBe
8

Я использовал его в том случае, когда что-то могло пойти не так в моем методе @Before.

public Object obj;

@Before
public void setUp() {
    // Do some set up
    obj = new Object();
}

@Test
public void testObjectManipulation() {
    if(obj == null) {
        fail("obj should not be null");
     }

    // Do some other valuable testing
}
Райан Д
источник
1
Да, предварительные условия для тестирования - это хорошо. Однако, если вы хотите убедиться, что @Beforeметод успешен, вероятно, лучше проверить его непосредственно в этом методе. В качестве бонуса, по крайней мере, JUnit и TestNG даже сообщат о другом сбое для ошибок из @Before/ @Aftermethods, так что можно увидеть, что проблема не в самом тесте.
sleske
4

Вот как я использую метод Fail.

Есть три состояния, в которых ваш тестовый пример может закончиться

  1. Пройдено: тестируемая функция успешно выполнилась и вернула данные, как ожидалось.
  2. Не пройден: тестируемая функция выполнена успешно, но возвращенные данные не соответствуют ожиданиям.
  3. Ошибка: функция не была выполнена успешно, и это не было

предназначено (в отличие от отрицательных тестовых случаев, которые ожидают возникновения исключения).

Если вы используете eclipse, три состояния обозначаются зеленым, синим и красным маркером соответственно.

Я использую операцию отказа для третьего сценария.

например: public Integer add (integer a, Integer b) {return new Integer (a.intValue () + b.intValue ())}

  1. Пройденный случай: a = новое целое число (1), b = новое целое число (2) и функция вернула 3
  2. Случай не пройден: a = новое целое число (1), b = новое целое число (2) и функция вернула значение soem, отличное от 3
  3. Неудачный случай: a = null, b = null, и функция выдает исключение NullPointerException
user3044364
источник
1
Если вы посмотрите исходный код JUnit, вы увидите, что утверждения используют fail().
Daniel C. Sobral
3

Я, например, использую fail()для обозначения тестов, которые еще не закончены (бывает); в противном случае они были бы успешными.

Возможно, это связано с тем, что я не знаю о какой-то неполной функции (), которая существует в NUnit.

Ален Сильжак
источник
2

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

Например:

final CountDownLatch latch = new CountDownLatch(1);

service.asyncCall(someParameter, new ResponseHandler<SomeType>() {
    @Override
    public void onSuccess(SomeType result) {
        assertNotNull(result);
        // Further test assertions on the result
        latch.countDown();
    }

    @Override
    public void onError(Exception e) {
        fail(exception.getMessage());
        latch.countDown();
    }
});

if ( !latch.await(5, TimeUnit.SECONDS) ) {
    fail("No response after 5s");
}
Рафаэль
источник
0

Вероятно, наиболее важным вариантом использования является проверка исключений.

Хотя junit4 включает ожидаемый элемент для проверки того, произошло ли исключение, похоже, что он не является частью более нового junit5. Еще одно преимущество использования fail()перед использованием expectedзаключается в том, что вы можете комбинировать его с finallyвозможностью очистки тестового примера.

dao.insert(obj);
try {
  dao.insert(obj);
  fail("No DuplicateKeyException thrown.");
} catch (DuplicateKeyException e) {
  assertEquals("Error code doesn't match", 123, e.getErrorCode());
} finally {
  //cleanup
  dao.delete(obj);
}

Как отмечено в другом комментарии. Также разумно иметь возможность провалить тест, пока вы не завершите его реализацию.

Удо Хельд
источник