仅在specs2单元测试(Scala)中遇到一些奇怪的强制转换异常

时间:2016-10-29 10:06:09

标签: scala unit-testing mockito

我有一个服务方法如下:

override def update(group: JourneyGroup, name: String, operator: User): Future[Either[String, JourneyGroup]] = {
    for {
      updatedCount <- journeyGroupDao.update(group.copy(name = name), operator.id.get)
      updatedGroup <- journeyGroupDao.findOneById(group.id.get)
    } yield
      (updatedCount, updatedGroup) match {

        case (1, Some(g)) =>
          system.eventStream.publish(JourneyGroupUpdated(g, group))
          Right(g)

        case (1, None) => Left(s"failed to find updated journey group object - ${group.id.get}")

        case _ => Left(s"failed to update journey group object - ${group.id.get}")

      }
  }

它的单元测试看起来像这样:

val existingGroup = mock[JourneyGroup]
      existingGroup.id returns Some(123)

      val updatedGroup = mock[JourneyGroup]

      val operator = mock[User]
      operator.id returns Some(876)

      doReturn(Future.successful(1)).when(journeyGroupDao).update(Matchers.any[JourneyGroup], Matchers.eq(876))
      doReturn(Future.successful(updatedGroup)).when(journeyGroupDao).findOneById(123, includeDeleted = false)
      doNothing.when(eventStream).publish(Matchers.any[JourneyGroupUpdated])

      val future = journeyGroupService.update(existingGroup, "new name", operator)
      Await.result(future, Duration.Inf) must beRight{ g: JourneyGroup =>

        g must_=== updatedGroup

      }
      there was one(eventStream).publish(Matchers.any[JourneyGroupUpdated])

该方法在常规执行中完美运行。但是,当我运行测试时,我得到了投射错误:

[error]    java.lang.ClassCastException: model.JourneyGroup$$EnhancerByMockitoWithCGLIB$$a9b16db0 cannot be cast to scala.Option (JourneyGroupService.scala:101)
[error] services.JourneyGroupServiceImpl$$anonfun$update$1$$anonfun$apply$1.apply(JourneyGroupService.scala:101)

我甚至不确定从哪里开始。我很感激任何想法。

1 个答案:

答案 0 :(得分:2)

在for-comprehension的代码中说返回类型为:

updatedGroup <- journeyGroupDao.findOneById(group.id.get)

Option[JourneyGroup],但在模拟互动的声明中,会给出JourneyGroup

val updatedGroup = mock[JourneyGroup]
...
doReturn(Future.successful(updatedGroup)).when(journeyGroupDao).findOneById(123, includeDeleted = false) 

updatedGroup必须是Option[JourneyGroup]

类型

那就是说,我不建议在Scala测试中使用模拟。使用traits和最小化实现将让编译器指出这些错误。模拟将这些检查移动到运行时并模糊了实际原因,就像在这种情况下一样。