ScalaTest异步测试结合Mockito mock对象时如何避免临时变量写法?
实现方案
1. 封装异步版本的mock工具方法
当前mockito-scala提供的withObjectMocked是为同步场景设计的,返回Unit属于预期行为,不是bug。你可以自行封装一个泛型的异步版本,既不需要临时变量,还能避免原有临时变量赋值写法的隐患:该写法会在withObjectMocked代码块执行结束后立即恢复对象原生实现,若测试的异步逻辑还未执行到对该Object的调用,mock会直接失效。
封装方法参考:
import org.mockito.MockitoSugar.withObjectMocked import scala.concurrent.{Future, Promise} def withObjectMockedAsync[T <: Singleton, R](obj: T)(f: => Future[R]): Future[R] = { val promise = Promise[R]() withObjectMocked(obj) { promise.completeWith(f) } promise.future }
2. 优化后的测试代码
使用封装好的方法后,测试代码可以直接返回Future[Assertion],无需临时变量:
class SomeTest extends AsyncWordSpec with Matchers with AsyncMockitoSugar with ResetMocksAfterEachAsyncTest { "no temp var needed now" in { withObjectMockedAsync(SomeObject) { when(SomeObject.someFunction(any)) thenReturn Left(Error("not found")) val mockDependency = mock[SomeDependency] val testClass = ClassBeingTested(mockDependency) testClass.giveMeAFuture("test_id") map { r => r should equal(Error("not found")) } } } }
相关疑问解答
- 使用
AsyncMockitoSugar后withObjectMocked仍然返回Unit是正常情况,当前官方版本并未针对异步场景适配Object mock的返回值。 - 可以向官方提交特性请求,要求在
AsyncMockitoSugar中新增返回代码块执行结果的异步版本withObjectMocked,属于合理的功能需求。
内容的提问来源于stack exchange,提问作者anqit
相关产品推荐
相关产品推荐

