模拟一个 class 方法来抛出异常,这样我就可以在真正的方法调用中测试异常场景
Mock a class method to throw an exception, so that I can test the exception scenario in a real method call
假设我有一个方法 guardedRun
,它在 Try 块中运行调用方法。我想测试 guardedRun
中的异常处理
object Task {
sealed trait TaskResponse
case class TaskReport(returnCode: Int = 0,
exception: Option[Throwable] = None) extends TaskResponse
...
...
}
abstract class Task {
def run(someVar: Map[String, Any]): Task.TaskResponse
def guardedRun(retry: Boolean,
someVar: Map[String, Any]) : Task.TaskResponse = {
Try(run(someVar)) match {
case Success(response) => response
case Failure(e) => e match {
case SomeSpecificException(msg, cause) =>
doStuffWithSomeSpecificException(msg, cause)
case _ =>
Task.TaskReport(exception = Some(e))
}
}
}
}
我特别想测试 run
returns 非 SomeSpecificException 的场景。
下面是我尝试使用 MockitoSugar 执行此操作
org.scalatestplus" %% "mockito-3-4" % "3.2.7.0" % "test"
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatestplus.mockito.MockitoSugar
class TaskTest extends AnyFlatSpec with MockitoSugar {
val mockTaskReport = mock[Task]
"guardedRun" should "return task report with exceptions in case task run throws exception" in {
when(mockTaskReport.run(someVar = any[Map[String, Any]]()))
.thenThrow(new Exception("something went wrong"))
doCallRealMethod()
.when(mockTaskReport)
.guardedRun(false, Map[String, Any]())
val response = mockTaskReport.guardedRun(retry = false, Map[String, Any]())
assert(response.asInstanceOf[TaskReport].exception.isDefined)
assertResult("something went wrong")(response.asInstanceOf[TaskReport].exception.get.getMessage)
}
}
然而,这会抛出来自 mockito 的异常
Checked exception is invalid for this method! Invalid: java.lang.Exception: something went wrong
一种可能的方法是从 run
方法中抛出异常,但我不想那样做;加上它打破了 Try 块
我发现 Exception
是一个已检查的异常,因此 运行 方法需要抛出 Exception
异常,因为它已被检查。
如果我在测试用例中抛出 RunTimeException(未选中),它会通过,这正是我想要的
假设我有一个方法 guardedRun
,它在 Try 块中运行调用方法。我想测试 guardedRun
object Task {
sealed trait TaskResponse
case class TaskReport(returnCode: Int = 0,
exception: Option[Throwable] = None) extends TaskResponse
...
...
}
abstract class Task {
def run(someVar: Map[String, Any]): Task.TaskResponse
def guardedRun(retry: Boolean,
someVar: Map[String, Any]) : Task.TaskResponse = {
Try(run(someVar)) match {
case Success(response) => response
case Failure(e) => e match {
case SomeSpecificException(msg, cause) =>
doStuffWithSomeSpecificException(msg, cause)
case _ =>
Task.TaskReport(exception = Some(e))
}
}
}
}
我特别想测试 run
returns 非 SomeSpecificException 的场景。
下面是我尝试使用 MockitoSugar 执行此操作
org.scalatestplus" %% "mockito-3-4" % "3.2.7.0" % "test"
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatestplus.mockito.MockitoSugar
class TaskTest extends AnyFlatSpec with MockitoSugar {
val mockTaskReport = mock[Task]
"guardedRun" should "return task report with exceptions in case task run throws exception" in {
when(mockTaskReport.run(someVar = any[Map[String, Any]]()))
.thenThrow(new Exception("something went wrong"))
doCallRealMethod()
.when(mockTaskReport)
.guardedRun(false, Map[String, Any]())
val response = mockTaskReport.guardedRun(retry = false, Map[String, Any]())
assert(response.asInstanceOf[TaskReport].exception.isDefined)
assertResult("something went wrong")(response.asInstanceOf[TaskReport].exception.get.getMessage)
}
}
然而,这会抛出来自 mockito 的异常
Checked exception is invalid for this method! Invalid: java.lang.Exception: something went wrong
一种可能的方法是从 run
方法中抛出异常,但我不想那样做;加上它打破了 Try 块
我发现 Exception
是一个已检查的异常,因此 运行 方法需要抛出 Exception
异常,因为它已被检查。
如果我在测试用例中抛出 RunTimeException(未选中),它会通过,这正是我想要的