【问题标题】:[Scala][Mokito] How to stub a Future function to throw exception[Scala][Mokito] 如何存根 Future 函数以引发异常
【发布时间】:2015-12-01 09:32:02
【问题描述】:

我正在编写用于存根存储库Future 函数的测试用例引发Exception 以模拟一些数据库错误。

我预计 Repository.create 会引发 DB 异常,它将由 Actor .recover{} 处理。但是会抛出异常,无法被.recover捕获

// test 
it should "return NOT created message if exception thrown" in {
    val repository = mock[Repository]
    val service = TestActorRef(props(repository))
    implicit val ec: ExecutionContext = service.dispatcher
    val mockTeam = mock[Team]

    when(repository.create(any[Team])(same(ec))).thenReturn(Future.failed(throw new Exception))
    service ! CreateTeam(mockTeam)
    expectMsg(TeamNotCreated())
}


// service == actor
override def receive = {
    case CreateTeam(team) => createTeam(team)
    .recover {
      case error: Exception => TeamNotCreated()
    }.pipeTo(sender())
}
private def createTeam(team: Team)
  : Future[TeamCreateEvent] = {
        for {
          newTeam <- repository.create(team = team)
        } yield {
          if (newTeam isDefined) TeamCreated(newTeam)
          else TeamNotCreated()
        }
      }

// repository
override def create(team: TeamEntity)(implicit ec: ExecutionContext)
  : Future[Option[TeamEntity]] = {
    Future {
      val column = Team.column
      /****  I want to simulate some exception was thrown here ***/
      val newId = Team.createWithNamedValues(
        column.name -> team.name
      )
      if (newId.isValidLong) Option(team.copy(id = newId)) else None
    }
  }

这是输出:

[info] - should return NOT created message if exception thrown *** FAILED ***
[info]   java.lang.Exception:
 should return updated message if collaborator team create success *** FAILED ***
[info]   org.mockito.exceptions.misusing.UnfinishedStubbingException: 

Unfinished stubbing detected here:
.g. thenReturn() may be missing.
[info] Examples of correct stubbing:
[info]     when(mock.isOk()).thenReturn(true);
[info]     when(mock.isOk()).thenThrow(exception);
[info]     doThrow(exception).when(mock).someVoidMethod();
[info] Hints:
[info]  1. missing thenReturn()
[info]  2. you are trying to stub a final method, you naughty developer!
[info]  3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed

我曾尝试将 thenReturn(Future.failed.. 替换为 thenThrow(new Exception),但无法使用错误 ava.lang.AssertionError: assertion failed: timeout (3 seconds) during expectMsg while waiting for

【问题讨论】:

    标签: scala akka mockito future stub


    【解决方案1】:

    您不想抛出 Future.failed 中的异常,只需在此处创建即可。在调用真实存储库时发生的情况是,在Future 的结果的计算 中抛出了一个异常,然后这将被捕获并放置在一个Failure 实例中,而不是而不是将成功的计算结果放在Success 实例中。所以:

    when(repository.create(any[Team])(same(ec))).thenReturn(Future.failed(new Exception(...)))
    

    应该做的工作。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-07
    • 2019-02-11
    • 2018-01-07
    • 2018-06-15
    • 2019-05-01
    • 1970-01-01
    • 2021-07-08
    • 2018-01-16
    相关资源
    最近更新 更多