scala - 将模拟 Actor 注入(inject) Spray 路线进行测试

标签 scala unit-testing akka spray spray-test

我部门的多个小组已经开始使用 Spray 来开发基于 REST 的 Web 服务,并且都遇到了类似的问题,到目前为止还没有很好的解决方案。

假设您有以下内容:

FooService extends Actor { ??? }

然后在其他地方:

path("SomePath") {
  id =>
    get {
      requestContext =>
        // I apologize for the janky Props usage here, just an example
        val fooService = actorRefFactory.actorOf(Props(new FooService(requestContext))) 
        queryService ! SomeMessage(id)
    }
}

换句话说,每个端点都有一个对应的actor,在路由内部,那种类型的actor会根据请求上下文启动,一条消息会传递给它,那个actor会处理HttpResponse &停止。

我一直有足够简单的路由树,我只对 Actors 本身进行了单元测试,并让集成测试处理路由测试,但我在这里被否决了。所以问题是对于单元测试,人们希望能够用 MockFooService

替换 FooService

是否有处理这种情况的标准方法?

最佳答案

我会选择蛋糕模式,您可以在最后一刻混合实现:

trait MyService extends HttpService with FooService {
  val route =
    path("SomePath") { id =>
        get { requestContext =>
            val fooService = actorRefFactory.actorOf(fooProps(requestContext)) 
            queryService ! SomeMessage(id)
        }
    }
}

trait FooService {
  def fooProps(requestContext: RequestContext): Props
}

trait TestFooService extends FooService {
  def fooProps(requestContext: RequestContext) =
    Props(new TestFooService(requestContext))
}

trait ProdFooService extends FooService {
  def fooProps(requestContext: RequestContext) =
    Props(new FooService(requestContext))
}

trait MyTestService extends MyService with TestFooService

trait MyProdService extends MyService with ProdFooService

我是用文本编辑器写的,所以我不确定它是否可以编译。

如果你想在没有 Actor 的情况下进行测试,你可以提取这两行:

val fooService = actorRefFactory.actorOf(fooProps(requestContext)) 
queryService ! SomeMessage(id)

进入某种方法并在其背后隐藏一个 Actor 。例如:

def processRequest[T](msg: T): Unit = {
  // those 2 lines, maybe pass other args here too like context
}

可以用相同的蛋糕模式方式覆盖此方法,对于测试,您甚至可以完全避免使用 Actor 。

关于scala - 将模拟 Actor 注入(inject) Spray 路线进行测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29112170/

相关文章:

Scala 编译时检查构造函数调用的位置

Scalatest 异步测试套件与最终和WhenReady (org.scalatest.concurrent)

java - 如何对预期在小程序安全管理器中运行的 Java 代码进行单元测试

android - 如何使用 Robolectric 检测以编程方式调用 onBackPressed?

websocket - 使用 akka http 通过网络套接字推送消息

java - MapReduce 程序中的洗牌步骤是否与映射并行运行?

scala - 如何比较scala中两种不同类型的对象?

c# - 为什么在单元测试中实例化ListView时SelectedIndices和SelectedItems不起作用?

scala - Akka Stream 在 Flow 中使用 HttpResponse

scala - Lagom -LagomServiceLocatorStart :Failed to start embedded Service Locator or Service Gateway?