Mockito를 사용하여 모의 객체에서 확인 된 예외를 throw하십시오.


173

특정 메소드가 호출 될 때 조롱 된 객체 중 하나가 확인 된 예외를 발생 시키려고합니다. 나는 다음을 시도하고있다.

@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 {
}

그러나 다음과 같은 오류가 발생합니다.

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 문서를 보면 Mockito를 사용 RuntimeException하여 모의 객체에서 확인 된 예외를 던질 수 없습니까?

답변:


221

Java API 목록을 확인하십시오 .
get(int index)메소드는 IndexOutOfBoundException어느 것을 확장 하도록 선언 됩니다 RuntimeException.
당신은 예외가 던져 Mockito을 말하려고하는 SomeException()것입니다 특정 메서드 호출에 의해 던져 질 유효하지를 .

더 명확히하기 위해. 목록 체크 예외를 제공하지 않는 인터페이스에서 발생되는 방법 Mockito가 실패하는 이유입니다. 조롱 된 List 를 만들 때 Mockito는 List정의를 사용합니다.
get(int index)
는 모의를 생성 할 수의 .class를.

메소드가 던지지 않아 Mockito가 실패 하기 때문에 로 지정하는 동작이 when(list.get(0)).thenThrow(new SomeException()) List API의 메소드 서명과 일치 get(int index)하지 않습니다SomeException() .

정말로 이것을 원한다면 , API가 유일하게 유효한 예외 임을 던지기 때문에 Mockito가 던지 new RuntimeException()거나 더 나은 던지기를하십시오 new ArrayIndexOutOfBoundsException().


내 실제 코드는 실제로 List를 사용하지 않지만 귀하의 답변은 해당 메소드 호출에도 적용됩니다. 나는 잘못된 방법을 조롱하고 있었다. 감사합니다.
Arthur Maltson

2
추가 : Mocktio는 throwables없이 메소드를 던질 경우 불평하지 않지만이 예외도 발생합니다
dwana

8
Kotliners의 경우 : Kotlin은 예외를 확인하지 않았으므로 함수 서명에서 함수가 예외를 발생시키는 것으로 일반적으로 선언 할 수 없습니다. 그러나 주석을 사용하여 함수에 Throws주석을 달아 컴파일러가 동등한 Java 코드에서 throw를 선언하는 것과 동일한 바이트 코드를 생성하도록 할 수 있습니다 . 자세한 내용은 [여기] ( kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/-throws/… )를 참조하십시오.
Javad Sadeqzadeh

1
이 검사는 Mockito 2.11.0 릴리스 이후 시행됩니다 (2.10.3 참조) .
JJD

106

해결 방법은 willAnswer() 것입니다.

예를 들어 다음은 다음을 사용하여 작동합니다 (그리고 던지지 MockitoException않지만 실제로 Exception필요한 경우 체크 를 던집니다 ) BDDMockito.

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

평범한 Mockito와 동등한 doAnswer방법으로


9
또는 willAnswer( invocation -> { throw new Exception("abc msg"); }).given(someObj).someMethod(stringArg1);메소드가을 리턴 할 때 사용 하십시오 void.
Julien Kronegg

9
또는 when (someObj.someMethod (stringArg1)). thenAnswer (invocation-> {throw new Exception ( "abc msg");});를 사용하십시오.
Dmitri Algazin 12

훌륭한 해결 방법, 감사합니다! 원활하게 확장 기능 및 (2)와 같은 여러 인수를 전달할 수 같은 것을 (1) 사용하고자하는 Kotliners를 들어 willThrow()일반적으로 허용, 내가 작성한 요점을
데이비드 페랑

2
또는 doAnswer에서nhaarman.mockitokotlin2
HMAC

6

일반적으로 Mockito 예외가 메시지 서명에 선언되어있는 한 확인 된 예외를 던질 수 있습니다. 예를 들어, 주어진

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

interface Foo {
  Bar frob() throws BarException
}

쓰는 것은 합법적입니다 :

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

그러나 메소드 서명에 선언되지 않은 확인 된 예외가 발생하는 경우 (예 :

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

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

Mockito는 런타임에 다소 오도하는 일반적인 메시지와 함께 실패합니다.

Checked exception is invalid for this method!
Invalid: QuxException

이것은 일반적으로 확인 된 예외가 지원되지 않는다고 믿게 할 수 있지만 실제로 Mockito는 확인 된 예외 가이 방법에 유효하지 않다고 말하려고합니다 .


5

Kotlin에는 해결책이 있습니다.

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

주어진 곳에서

수입 org.mockito.BDDMockito.given


1

이것은 Kotlin에서 저에게 효과적입니다.

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

참고 : Exception () 이외의 정의 된 예외를 모두 처리하십시오.


내가 찾던 것 외에는 예외를 던질 수 있습니다Exception
Naeem Sarfraz
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.