简体   繁体   English

如何在Groovy Spock测试中注入模拟的Ratpack客户端

[英]How to inject mocked ratpack client in Groovy spock test

I'm new to Kotlin and Groovy and not sure how feasible it is to achieve this. 我是Kotlin和Groovy的新手,并且不确定实现此目标的可行性。

I have an http client that makes remote calls 我有一个HTTP客户端,可以进行远程呼叫

class MyClient @Inject constructor(private val httpClient: HttpClient, private val config: MyConfig) {

  fun GetStuff(id: Id): Promise<MyResponse> { ...}
}

Then there MyApiApp configuration with random binding and registrations 然后是带有随机绑定和注册的MyApiApp配置

And then an AbstractModule which from what I can see an external library to create a more readable configuration: 然后是一个AbstractModule,从中可以看到一个外部库来创建更具可读性的配置:

class ApiModule : AbstractModule() {
  protected override fun configure() {
    bind(MyEndpoint::class.java)
  }

MyEndpoint gets injected into the configuration of myApp and the endpoints become available. MyEndpoint被注入到myApp的配置中,并且端点变为可用。 The endpoint works well but the below is a pseudocode that shows roughly what it does. 端点运行良好,但是下面的伪代码大致显示了它的作用。

class MyEndpoint @Inject constructor(val mClient:MyClient) : Action<Chain> {
  override fun execute(chain: Chain) {
    chain.path("foo") { ctx ->
      ctx.byMethod { method ->
        method
            .post { ->
              ctx.request.body
                  .then { requestBody ->
                    Blocking.get {
                      val id = OBJECT_MAPPER.readValue(requestBody.getText(), Id::class.java)
                      val data: ComponentResult<MyResponse> = Blocking.on(myClient.GetStuff(id))

                      data.result!!
                    }
                        .onError { throw Exception(it.message) }
                        .then { tx.response.status(HttpResponseStatus.OK.code()).send() }
                  }
            }
         }
      }
   }
}

And now to the question. 现在到这个问题。 I am writing groovy integration tests and I want to make httpCall to my ratpack server but I want the subsequent calls to myClient to be mocked to eliminate dependencies. 我正在编写groovy集成测试,并且想对我的ratpack服务器进行httpCall,但是我希望对随后对myClient的调用进行模拟以消除依赖关系。

@Shared UUID Id= UUID.fromString("c379ad2f-fca4-485c-a676-6988e2c8ef82")
private MyClient mockClient = GroovyMock(MyClient)
private MyEndpoint myEndpoint = new MyEndpoint(mockClient)

@AutoCleanup
private aut = new MainClassApplicationUnderTest(MyApiApp) {

    @Override
    protected void addImpositions(final ImpositionsSpec impositions) {
      impositions.add(BindingsImposition.of {
        it.bindInstance (MyEndpoint, myEndpoint)
      })
    }
  }

  @Delegate
  TestHttpClient client = aut.httpClient

  void 'Make a call and the client should be mocked'() {
    when:
    final response = client.requestSpec { spec ->
      spec.body { b ->
        b.type("application/json")
        b.text("{\"Id\": \"$Id \"}")
      }
    }.post('foo')

    then:
    1 * mockClient.GetStuff(Id) >> { throw new Exception("Fail") }

    and:
    response.status.code == 500
  }

And here lies the problem. 问题就在这里。 The endpoint foo gets hit successfully but the myClient isn't mocked. 端点foo被成功命中,但是myClient没有被模拟。 the BindingImposition does something because it replaces myClient with one that has null HttpClient inside it. BindingImposition之所以会执行某些操作,是因为它将myClient替换为其中具有空HttpClient的myClient。

Is it somehow possible to inject a mocked client into my endpoint? 是否可以将模拟的客户端注入我的端点? I would prefer not to create an EmbeddedApp, but to just mock MyClient. 我宁愿不要创建EmbeddedApp,而要模拟MyClient。 I also tried UserRegistryImpositions but so far I haven't managed to properly mock MyClient. 我也尝试了UserRegistryImpositions,但到目前为止,我还没有设法正确模拟MyClient。

I have achieved this using .NET Core 2, but haven't found the way using this framework. 我已经使用.NET Core 2实现了此目标,但是还没有找到使用此框架的方法。

Any help is very appreciated. 任何帮助都非常感谢。 Thanks 谢谢

我通过使用接口使其工作

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM