问题描述
据我所知,Scala没有检查异常,即我不需要指定方法将抛出的异常。
我正在测试类A
的方法a
。它调用类B
的方法b
。我想测试B
引发异常时的行为。
class b{
def B()={...}
}
我嘲笑了B
when(mockB.B).thenThrow(new UserDoesNotExistException("exception"))
执行此操作时,出现错误Checked exception is invalid for this method!
此答案解释了w.r.t. Java
-throw checked Exceptions from mocks with Mockito
虽然将UserDoesNotExistException
更改为RuntimeException
对我有用,但我很好奇我是否可以通过抛出UserDoesNotExistException
根据我的逻辑,A
具有不同的路径,这取决于引发哪种异常,因此,我需要从测试中引发特定的异常,而不是引发泛型的RuntimeException
。
解决方法
简短的回答是可以。你该怎么做?您需要将throws注释添加到B方法中:
class b{
@throws(classOf[UserDoesNotExistException])
def B()={...}
}
根据Scala Cookbook关于抛出注释的说明:
首先,无论消费者使用的是Scala还是Java,如果他们正在编写功能强大的代码,那么他们都想知道失败了。其次,如果他们使用Java,则@throws注释是Scala向Java使用者提供throws方法签名的Scala方法。
由于Mockito.java是用Java编写的,因此它必须知道可以引发哪些用户异常。不应该显式编写RuntimeException,因为它总是可以抛出。
另一种可能的解决方案是升级到最新的Mockito-scala(目前为1.15.0版),您可以使用:
org.mockito.MockitoSugar.when
这是纯scala,然后下面的代码应该起作用:
import org.mockito.MockitoSugar.{mock,when}
val bMock = mock[b]
when(bMock.B()).thenThrow(new UserDoesNotExistException("exception"))
,
thenAnswer
也有效-
when(mockB.B).thenAnswer(invocation=>throw new UserDoesNotExistException("exception"))