Mockito Atılan bir istisna ile nasıl dalga geçilir ve iddia edilir?


Yanıtlar:


75

BDD Style Solution (Java 8'e güncellendi)

Tek başına Mockito istisnaları ele almak için en iyi çözüm değildir, Catch-Exception ile Mockito kullanın

Mockito + Catch-Exception + AssertJ

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

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

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

Basit kod

Bağımlılıklar


2
"İstisna yakalama" nedir? Bağlantınız var mı?
Duncan Jones

ne caughtException?
Saif Masadeh

Anladım, geliyorcom.googlecode.catchexception.CatchException.caughtException;
Saif Masadeh

212

Önce ikinci sorunuzu cevaplamak için. JUnit 4 kullanıyorsanız, testinize ek açıklama ekleyebilirsiniz.

@Test(expected=MyException.class)

bir istisnanın meydana geldiğini iddia etmek için. Mockito ile bir istisna "taklit etmek" için şunu kullanın:

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

2
Bu yaklaşım, bir durumu olan bir nesnenin yöntemini test ettiğinizde kabul edilemez. Örneğin, ikinci kez çağırırsanız istisna atan bir nesne yöntemi vardır. Ve birincisi değil, ikinci yöntem çağrısı sırasında istisna atıp atmadığını test etmeniz gerekir. İlk yöntem çağrısı sırasında (hazırlık aşamasında) MyException atarsa, testte başarısız olmalıdır. Ancak bu yaklaşımla, istisnanın hangi yöntem çağrısı sırasında atıldığını kontrol edemiyoruz.
Sneg

Yine de bu durumda, ilk yöntem çağrısından istisnayı yakalayabilir ve RuntimeException içine sarabiliriz.
Sneg

29

İstisna mesajını da test etmek istiyorsanız, JUnit's ExpectedException'ı Mockito ile kullanabilirsiniz:

@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()bu nereden geliyor?
Mohammad Faisal


Ayrıca @ Kuralını kullanmayı tercih ederim, çünkü bu şekilde beklenen mesajı veya nedeni veya istisnayla ilgili diğer şeyleri test edebilirim. Özel durumun nedenini kontrol etmek için, beklenenException.expectCause (Mockito.sameInstance (beklenenException)) veya beklenenException.expectCause (Mockito.instanceOf (MyException.class)) ve kullanışlı olan birkaç tane daha kullanıyorum.
Crenguta S

19

06/19/2015 için güncellenmiş yanıt (java 8 kullanıyorsanız)

Sadece assertj kullanın

Assertj-core-3.0.0 + Java 8 Lambdas'ı kullanma

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

Referans: http://blog.codeleak.pl/2015/04/junit-testing-exceptions-with-java-8.html


benim için çalıştı ... Ayrıca istisna mesajını da kontrol edebiliriz.assertThatThrownBy (() -> myService.sumTingWong ("badArg")). hasMessage ("test") .isInstanceOf (IllegalArgumentException.class);
Sritam Jagadev

17

JUnit 4 ve Mockito 1.10.x kullanıyorsanız, test yönteminize aşağıdakilerle açıklama ekleyin:

@Test(expected = AnyException.class)

ve istediğiniz istisna kullanımı atmak için:

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

16

İstisnayı şu şekilde yapın:

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

Ya testinizin böyle bir istisna atacağını iddia ederek bunun gerçekleştiğini doğrulayın:

@Test(expected = AnException.class)

Veya normal sahte doğrulama ile:

verify(obj).someMethod();

İkinci seçenek, testiniz ara kodun istisnayı işlediğini kanıtlamak için tasarlandıysa gereklidir (yani istisna test yönteminizden atılmaz).


Does verifyistisna assert çağrıyı?
NilsH

@NilsH Hayır. Ancak whencümle doğruysa, bir istisna atmış olmalı.
Duncan Jones

10

Mockito'nun doThrow'unu kullanın ve daha sonra atıldığını iddia etmek için istenen istisnayı yakalayın.

@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 kullanarak istisnayı gerçekleştirebilirsiniz.

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

Junit5'i kullanarak, bir istisna belirleyebilir, test yöntemi çağrıldığında bu istisnanın atılıp atılmadığını ileri sürebilirsiniz .

@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());
}

Burada bir örnek bulun: istisna ileri sürün


Teşekkürler ! Benim için çalıştı
HariKishore

1

Mockito ile ilgisi olmayan kişi istisnayı yakalayabilir ve özelliklerini öne sürebilir. İstisnanın gerçekleştiğini doğrulamak için, istisnayı atan ifadeden sonra try bloğu içinde yanlış bir koşul ileri sürün.


@MariuszS yanıtı, söylediklerinizin Mockito ile ilgisi olmadığını doğru yanıtlıyor
pringi

@pringi Teşekkürler, sorunun hem bir istisnayı alay etmek hem de onu yakalamakla ilgili olduğunu görüyorum. Bunun test edilen kodun herhangi bir davranışına bağlı olup olmadığını merak ediyorum.
eel ghEEz

1

Veya istisnanız bir sınıfın yapıcısından atılırsa:

@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

İstisna mesajıyla onaylayın:

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

Bu şekilde yazılırsa, herhangi bir istisna atılmadığında, test yine de geçecektir . İlk başta kaçınmak istediğimiz şey bu
Christian Lim
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.