You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pekko Actors替换Akka后Mocking失效,请求命中真实数据库问题

Pekko Actors切换后Mocking测试失效的原因分析

从你提供的代码来看,Mocking失效直接命中真实数据库的核心原因是你创建的Mock对象根本没被路由使用,具体问题如下:

1. Mock实例与路由依赖不匹配

你在测试中创建了readerRepository这个Mock实例,但后续设置Mock预期时,却针对ReaderRepository(真实实现类或其伴生对象)进行Stub:

// 创建了Mock实例
private val readerRepository: ReaderRepositoryTrait = mock[ReaderRepositoryTrait]
// 但Stub的是真实类的方法,而非Mock实例
when(ReaderRepository.getData(any[Span])).thenReturn(Future.successful(DataList))

而你的路由allRoutes大概率是直接调用ReaderRepository.getData这个真实实现的方法,完全没用到测试中创建的Mock对象,自然会命中真实数据库。

2. 路由未采用依赖注入方式

你的路由代码应该是硬编码依赖了ReaderRepository的静态实现,而非通过构造参数或DI容器注入ReaderRepositoryTrait接口。这种情况下,即使切换到Pekko,测试也无法替换成Mock实例——因为路由根本没有预留依赖替换的入口。

修复方案

步骤1:重构路由,依赖接口而非具体实现

修改路由的定义,让它通过构造参数接收ReaderRepositoryTrait实例,比如:

class ReaderRoutes(readerRepo: ReaderRepositoryTrait) extends JsonSupport {
  val allRoutes: Route = {
    path("get-data-from-db") {
      get {
        // 使用注入的readerRepo实例,而非直接调用ReaderRepository
        onSuccess(readerRepo.getData(/* span参数 */)) { data =>
          complete(StatusCodes.OK, /* 响应内容 */)
        }
      }
    }
  }
}

步骤2:在测试中传入Mock实例并Stub其方法

修改测试代码,确保路由使用你创建的Mock实例,并针对Mock实例设置预期:

class ReaderTest extends AnyWordSpec with Matchers with ScalatestRouteTest with MockitoSugar with JsonSupport {
  private val readerRepository: ReaderRepositoryTrait = mock[ReaderRepositoryTrait]
  // 创建路由时传入Mock实例
  private val allRoutes = new ReaderRoutes(readerRepository).allRoutes

  // ... 其他测试数据定义 ...

  "The Service" should {
    "return a Response in JSON for GET request with path (/get-data-from-db)" in {
      // 针对Mock实例Stub方法
      when(readerRepository.getData(any[Span])).thenReturn(Future.successful(dataList))

      Get("/get-data-from-db") ~> allRoutes ~> check {
        status shouldEqual StatusCodes.OK
        contentType shouldEqual ContentTypes.`application/json`
        responseAs[String] shouldEqual routeResponseMessage.getResponse(StatusCodes.OK.intValue
          , ServerMessage.GET_SUCCESSFULLY_ALL, getAllJsonResponse).toString()
      }
    }
 }
}

额外检查点

  • 确保ReaderRepository的真实实现是ReaderRepositoryTrait的子类,且路由不再直接调用其静态方法或单例方法。
  • 若使用DI容器(如Guice),需确认测试环境下已将ReaderRepositoryTrait的绑定替换为Mock实例。

内容的提问来源于stack exchange,提问作者Syed Shaheer Ali Zaidi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 14:41:03