如何使用Scala和Mockito测试异步副作用

时间:2016-03-06 15:22:07

标签: scala mockito

我有一个简单的场景,我在第三方服务上做了一些工作,如果其中一个服务器出现故障,那么我想清理已完成的工作。

客户端不需要等待清理完成以获得响应,因此清理作为副作用,async函数完成。

在使用Mockito时,我希望verify调用清理方法,但是我遇到了竞争条件和非确定性测试。

以下是代码段:

val eventualImage = imageService.saveImage(uploadedImage, None, parent, imageActions)
ScalaFutures.whenReady(eventualImage.failed, timeout(6 seconds), interval(15 millis)) { ex =>
  val x = Mockito.verify(mockS3Repository, Mockito.times(1)).deleteFileFromS3(s3Location) // where this function is pure async and nothing is waiting for her to complete
  ex shouldBe a [exception.type]
}

有没有什么方法可以让我完成而无需更改我的代码?

2 个答案:

答案 0 :(得分:2)

您可以通过调用timeout-based verification方法timeout来执行此操作。

Mockito.verify(mockS3Repository, Mockito.timeout(5000)).deleteFileFromS3(s3Location)

虽然您不需要times(1),因为这是默认行为,您可以通过调用timeout(5000).times(1)等将两者联系在一起。

答案 1 :(得分:2)

正如@Lodewijk Bogaards在评论中所说。 使用最终块解决了我的问题。

这是一个例子:

首先将with Eventually添加到您的班级声明

然后问题中的代码将如下完成:

      val eventualImage = imageService.saveImage(uploadedImage, None, parent, imageActions)
      ScalaFutures.whenReady(eventualImage.failed, timeout(6 seconds), interval(15 millis)) { ex =>
        ex shouldBe a [exception.type]
        eventually(timeout(6 seconds), interval(15 millis)){
          Mockito.verify(mockS3Repository, Mockito.times(1)).deleteFileFromS3(s3Location)
        }
      }