代码之家  ›  专栏  ›  技术社区  ›  geoffjentry

将模拟演员注入喷雾路线进行测试

  •  3
  • geoffjentry  · 技术社区  · 10 年前

    我所在部门的多个小组已经开始使用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)
        }
    }
    

    换言之,每个端点都有一个对应的参与者,在路由内,该类型的参与者将与请求上下文一起旋转,消息将传递给它,该参与者将处理HttpResponse&停止

    我一直有足够简单的路由树,我只对Actor本身进行了单元测试,并让集成测试来处理路由测试,但我在这里被否决了。所以问题是,对于单元测试,人们希望能够替换 食品服务 用一个 模拟食品服务

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

    1 回复  |  直到 10 年前
        1
  •  3
  •   yǝsʞǝla    10 年前

    我将采用蛋糕模式,您可以在最后一刻混合实现:

    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
    

    我是在文本编辑器中编写的,所以我不确定它是否能编译。

    如果您想在没有参与者的情况下进行测试,可以提取以下两行:

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

    用某种方法隐藏一个演员。例如:

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

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