Mockito ile alaylardan istisnalar attı


173

Alaycı nesnelerimden biri belirli bir yöntem çağrıldığında kontrol edilen bir istisna atmaya çalışıyorum. Aşağıdakileri deniyorum.

@Test(expectedExceptions = SomeException.class)
public void throwCheckedException() {
    List<String> list = mock(List.class);
    when(list.get(0)).thenThrow(new SomeException());
    String test = list.get(0);
}

public class SomeException extends Exception {
}

Ancak, bu aşağıdaki hatayı üretir.

org.testng.TestException: 
Expected exception com.testing.MockitoCheckedExceptions$SomeException but got org.mockito.exceptions.base.MockitoException: 
Checked exception is invalid for this method!
Invalid: com.testing.MockitoCheckedExceptions$SomeException

Mockito belgelerine bakıldığında, sadeceRuntimeException , Mockito ile sahte bir nesneden kontrol edilen İstisnalar atmak mümkün değil mi?

Yanıtlar:


221

Liste için Java API'sini kontrol edin . Yöntem yalnızca atmak ilan edilir uzanan . Bir istisna atmak için Mockito anlatmaya çalıştığınız olduğunu o belirli yöntem çağrısıyla atılmak geçerli değil .
get(int index)IndexOutOfBoundExceptionRuntimeException
SomeException()

Daha fazla açıklığa kavuşturmak için. Liste bir kontrol İstisna sağlamaz arayüz gelen atılmasına yöntemi ve mockito başarısız neden olmasıdır. Eğer oluşturduğunuzda alay Listesini , mockito kullanacak Liste tanımını onun alay oluşturur .class.
get(int index)

Belirttiğiniz davranış when(list.get(0)).thenThrow(new SomeException()) , Liste API'sındaki yöntem imzasıyla eşleşmiyor , çünkü get(int index)yöntem atmıyorSomeException()Belirttiğiniz Mockito'nun başarısız olması için atmıyor.

Bunu gerçekten yapmak istiyorsanız , API, bunun atılacak tek geçerli İstisna olduğunu belirlediğinden, Mockito'ya bir new RuntimeException()veya daha iyi bir atış yapmasını sağlayın new ArrayIndexOutOfBoundsException().


Gerçek kodum aslında List'i kullanmadığı halde, cevabınız bu yöntem çağrısı için de geçerlidir. Yanlış yöntemle alay ediyordum. Teşekkür ederim.
Arthur Maltson

2
Ekstra: Mocktio eğer yaparsanız şikayet etmeyecekHerhangi bir sarf malzemesi olmadan bir yöntem atın, ancak bu istisnayı da alacaksınız
dwana

8
Kotliners için: Kotlin istisnaları kontrol etmediğinden, normalde işlevin bir istisna attığını (işlev imzasında) beyan edemezsiniz. Ancak, Throwsderleyicinin eşdeğer Java koduna atanma ile aynı bayt kodunu oluşturmasını sağlamak için işleve açıklama ekleyerek açıklama ekleyebilirsiniz . Daha fazla bilgi için [buraya] ( kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/-throws/… ) bakın.
Javad Sadeqzadeh

1
Bu kontrol Mockito 2.11.0 sürümünden beri uygulanmaktadır (bkz. 2.10.3) .
JJD

106

Çözüm, bir willAnswer()yöntem kullanmaktır .

Örneğin, aşağıdakileri kullanarak çalışır (ve MockitoExceptionatar, ancak Exceptionburada gerektiği gibi bir kontrol atar ) BDDMockito:

given(someObj.someMethod(stringArg1)).willAnswer( invocation -> { throw new Exception("abc msg"); });

Düz Mockito'nun eşdeğeri doAnsweryöntemi kullanacaktır


9
veya willAnswer( invocation -> { throw new Exception("abc msg"); }).given(someObj).someMethod(stringArg1);yöntem döndüğünde kullanın void.
Julien Kronegg

9
veya when (someObj.someMethod (stringArg1)). öğesini kullanın. thenAnswer (invocation -> {new Exception ("abc msg");});
Dmitri Algazin

Harika bir çözüm, teşekkürler! (1) Bunu sorunsuz bir şekilde bir uzatma fonksiyonu olarak kullanmak ve (2) willThrow()normalde izin verdiği gibi birkaç argümanı geçmek isteyen Kotliners için , bir Gist
David Ferrand

2
veya doAnsweritibarennhaarman.mockitokotlin2
hmac

6

Genel olarak, mockito o Not gelmez kadar uzun istisna mesajı imza açıkça belirtildiği gibi kontrol durumlar atma izin verir. Örneğin,

class BarException extends Exception {
  // this is a checked exception
}

interface Foo {
  Bar frob() throws BarException
}

yazmak yasaldır:

Foo foo = mock(Foo.class);
when(foo.frob()).thenThrow(BarException.class)

Ancak, yöntem imzasında bildirilmeyen bir işaretli istisna atarsanız, ör.

class QuxException extends Exception {
  // a different checked exception
}

Foo foo = mock(Foo.class);
when(foo.frob()).thenThrow(QuxException.class)

Mockito çalışma zamanında biraz yanıltıcı, genel bir mesajla başarısız olacaktır:

Checked exception is invalid for this method!
Invalid: QuxException

Bu, genel olarak kontrol edilen istisnaların desteklenmediğine inanmanıza neden olabilir, ancak aslında Mockito sadece bu kontrol edilen istisnanın bu yöntem için geçerli olmadığını söylemeye çalışmaktadır .


5

Kotlin ile çözüm var:

given(myObject.myCall()).willAnswer {
    throw IOException("Ooops")
}

Verilen yer nereden geliyor?

import org.mockito.BDDMockito.given


1

Bu benim için Kotlin'de çalışıyor:

when(list.get(0)).thenThrow(new ArrayIndexOutOfBoundsException());

Not: İstisna () dışında tanımlı herhangi bir istisnayı atın


Aradığım şey, dışında herhangi bir istisna atabilirException
Naeem Sarfraz
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.