Мокіто Як знущатися та стверджувати закинутий виняток?


Відповіді:


75

BDD Style Solution (оновлено до Java 8)

Mockito поодинці - не найкраще рішення для обробки винятків, використовуйте Mockito з Catch-Exception

Mockito + Catch-Exception + AssertJ

given(otherServiceMock.bar()).willThrow(new MyException());

when(() -> myService.foo());

then(caughtException()).isInstanceOf(MyException.class);

Зразок коду

Залежності


2
Що таке "вилов-виняток"? Отримали посилання?
Данкан Джонс

що caughtException?
Сайф Масаде

Зрозумів, це походитьcom.googlecode.catchexception.CatchException.caughtException;
Сайф Масаде

212

Щоб відповісти на ваше друге запитання першим. Якщо ви використовуєте JUnit 4, ви можете анотувати свій тест

@Test(expected=MyException.class)

стверджувати, що стався виняток. І щоб "знущатися над" винятком з макетом, використовуйте

when(myMock.doSomething()).thenThrow(new MyException());

2
такий підхід неприйнятний для випадку, коли ви перевіряєте метод тестування об'єкта, який має певний стан. Наприклад, існує об'єктний метод, який викидає виняток, якщо ви називаєте його вдруге. І вам потрібно перевірити, щоб перевірити, чи він робить викид під час виклику другого методу, а не першого. Якщо він кидає MyException під час першого виклику методу (на етапі підготовки), він повинен провалити тест. Але при такому підході ми не в змозі перевірити, під час якого виклику методу викидається виняток.
Снег

Хоча в цьому випадку ми можемо зловити виняток із першого виклику методу та обгорнути його у RuntimeException.
Снег

29

Якщо ви хочете також перевірити повідомлення про виняток, ви можете скористатись очікуваним розширенням JUnit з Mockito:

@Rule
public ExpectedException expectedException = ExpectedException.none();

@Test
public void testExceptionMessage() throws Exception {
    expectedException.expect(AnyException.class);
    expectedException.expectMessage("The expected message");

    given(foo.bar()).willThrow(new AnyException("The expected message"));
}

given()звідки це походить?
Мохаммед Фейсал


Я також вважаю за краще використовувати @Rule, тому що таким чином я можу перевірити очікуване повідомлення чи причину чи інші речі, що стосуються винятку. Для перевірки причини винятку я використовую: очікуваніException.expectCause (Mockito.sameInstance (очікуваніException)) або очікуваніException.expectCause (Mockito.instanOf (MyException.class)) та кілька інших, які корисні.
Кренгута S

19

Оновлена ​​відповідь за 19.06.2015 (якщо ви використовуєте java 8)

Просто використовуйте assrtj

Використання assertj-core-3.0.0 + Java 8 лямбда

@Test
public void shouldThrowIllegalArgumentExceptionWhenPassingBadArg() {
assertThatThrownBy(() -> myService.sumTingWong("badArg"))
                                  .isInstanceOf(IllegalArgumentException.class);
}

Довідка: http://blog.codeleak.pl/2015/04/junit-testing-exceptions-with-java-8.html


працював для мене ... Також ми можемо перевірити повідомлення про виняток також.assertThatThrownBy (() -> myService.sumTingWong ("badArg")). hasMessage ("test") .isInstanceOf (IllegalArgumentException.class);
Sritam Jagadev

17

Якщо ви використовуєте JUnit 4 та Mockito 1.10.x Анотувати свій метод тестування за допомогою:

@Test(expected = AnyException.class)

і кинути бажаний виняток:

Mockito.doThrow(new AnyException()).when(obj).callAnyMethod();

16

Зробіть виняток таким чином:

when(obj.someMethod()).thenThrow(new AnException());

Переконайтеся, що це сталося або запевнивши, що ваш тест викине такий виняток:

@Test(expected = AnException.class)

Або за допомогою звичайної макетної перевірки:

verify(obj).someMethod();

Остання опція необхідна, якщо ваш тест призначений для доказу проміжного коду, який обробляє виняток (тобто виняток не буде викинуто з вашого методу тестування).


Чи підтверджує verifyвиклик виняток?
NilsH

@NilsH Ні. Але якщо whenзастереження правильне, воно повинно викинути виняток.
Данкан Джонс

10

Використовуйте MoTito's doThrow, а потім виберіть потрібний виняток, щоб стверджувати, що він був кинутий пізніше.

@Test
public void fooShouldThrowMyException() {
    // given
    val myClass = new MyClass();
    val arg = mock(MyArgument.class);
    doThrow(MyException.class).when(arg).argMethod(any());
    Exception exception = null;

    // when
    try {
        myClass.foo(arg);
    } catch (MyException t) {
        exception = t;
    }

    // then
    assertNotNull(exception);
}

5

Використовуючи mockito, ви можете зробити виняток.

when(testingClassObj.testSomeMethod).thenThrow(new CustomException());

Використовуючи Junit5, ви можете стверджувати виняток, і стверджує, що це виключення кидається, коли викликається метод тестування .

@Test
@DisplayName("Test assert exception")
void testCustomException(TestInfo testInfo) {
    final ExpectCustomException expectEx = new ExpectCustomException();

     InvalidParameterCountException exception = assertThrows(InvalidParameterCountException.class, () -> {
            expectEx.constructErrorMessage("sample ","error");
        });
    assertEquals("Invalid parametercount: expected=3, passed=2", exception.getMessage());
}

Знайдіть зразок тут: стверджуйте виняток виключення


Дякую ! Працював для мене
HariKishore

1

Не пов’язаний з макетом, можна зловити виняток і стверджувати його властивості. Щоб переконатися, що виняток стався, встановіть помилкову умову в блоці спробу після заяви, яка видаляє виняток.


@MariuszS відповідь правильно відповідає, що ви говорите, не має відношення до Mockito
pringi

@pringi Дякую, я бачу, що питання стосувалося як глузування з винятку, так і його вирішення. Мені цікаво, хоча це залежить від будь-якої поведінки тестуваного коду.
вугор ghEEz

1

Або якщо ваш виняток викинуто з конструктора класу:

@Rule
public ExpectedException exception = ExpectedException.none();

@Test
public void myTest() {    

    exception.expect(MyException.class);
    CustomClass myClass= mock(CustomClass.class);
    doThrow(new MyException("constructor failed")).when(myClass);  

}

-1

Повідомлення за винятком повідомлення:

    try {
        MyAgent.getNameByNode("d");
    } catch (Exception e) {
        Assert.assertEquals("Failed to fetch data.", e.getMessage());
    }

Якщо написано , як це, коли немає НЕ виняток кинуто, тест буде ще пройти . Чого ми хочемо уникати в першу чергу
Christian Lim
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.