我正在为运行主要功能然后异步记录有关请求的详细信息的方法编写单元测试。
def someMethod(data: Object): SomeType =
for {
result <- someOtherMethod(data).withLogging(logMethod)
}
logMethod
方法是一个异步任务。在我的测试中,我想确保记录器正在接收一条消息,但是,线程有时会完成得太快,从而使测试不稳定,有时会导致 Unsatisfied
结果。
示例测试用例:
it("logs an error if an upload was attempted with some failure case") {
val uploadData = someData
mockSomeCall()
mockAnotherCall()
testController.methodWeAreTesting(uploadData).shouldBeRight()
Thread.sleep(75)
(stubLogger
.warn(_: RichMsg, _: Throwable, _: AnyId)(_: () => SourceLocation))
.verify(where { (msg: RichMsg, _, _, _) =>
msg.toString.equals(s"Some specific message")
})
}
每次我需要确保记录器接收到特定消息时,我都不喜欢添加 Thread.sleep
。我希望能够包装 stubLogger
期望。
如果需要更多信息,请告诉我。
最佳答案
我认为 promise
是您需要在 logMethod
中添加的内容。
根据 documentation :
While futures are defined as a type of read-only placeholder object created for a result which doesn’t yet exist, a promise can be thought of as a writable, single-assignment container, which completes a future. That is, a promise can be used to successfully complete a future with a value (by “completing” the promise) using the success method. Conversely, a promise can also be used to complete a future with an exception, by failing the promise, using the failure method.
A promise p completes the future returned by p.future. This future is specific to the promise p. Depending on the implementation, it may be the case that p.future eq p.
在测试中,一旦得到结果,就可以将结果与您尝试比较的消息进行比较。
示例代码如下:
object Test1 extends App {
import scala.concurrent.{Future, Promise}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.{Success, Failure}
var promiseMessage: String = _
val promise = Promise[String] //The promise will hold a string
//A future tells the System to spawn a new thread and run the code block inside it
val logMethod = (elem: String) => Future{
promise.success(elem)
elem
}
def method(data: String): Future[String] = {
for {
result <- logMethod(data)
} yield result
}
val f1 = method("Hi!! I love scala async programming")
promise completeWith f1
val promiseFuture = promise.future
promiseFuture onComplete {
case Success(value) =>
promiseMessage = value
println(promiseMessage)
case Failure(ex) => println(ex)
}
Await.result(promiseFuture, 100 seconds)
if (promiseMessage == "Hi!! I love scala async programming") println("correct")
}
在代码中,promise
是一个 Promise 对象,它在 future 完成时 promise 一个字符串。您需要做的就是用 future 完成 promise ,如下所示:
promise completeWith f1
然后,使用 promiseFuture onComplete
添加一个处理程序,说明在成功或失败时要做什么。
如果你想检查日志记录是否发生,你可以在 promiseFuture
上 await
或者继续进一步的过程,当日志记录完成时,promise 将打印成功如代码所示。
让我知道它有帮助!!
关于multithreading - Scala 避免异步测试用例的线程休眠,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60569006/