首页 > 解决方案 > 模拟一个类方法抛出异常,这样我就可以在真实的方法调用中测试异常场景

问题描述

假设我有一个在TryguardedRun中运行调用方法的方法。我想测试异常处理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返回非 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

标签: scalamockito

解决方案


我发现它Exception是一个已检查的异常,因此 run 方法需要抛出Exception异常,因为它已被检查。

如果我在测试用例中抛出 RunTimeException(未选中),它将通过,这就是我想要的


推荐阅读