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

Citrus框架异步HTTP测试场景

  •  0
  • supertramp  · 技术社区  · 9 年前

    我有一个异步测试场景。我调用我的SUT(测试中的系统),它返回确认响应。接下来,异步返回正确的响应。我配置了指定接收回调响应的模拟服务器,如下所示:

    <citrus-http:server id="receiveCallbackMockService"
          port="${server.port}"
          auto-start="true"
          timeout="10000"
          endpoint-adapter="dispatchingEndpointAdapter" />
    
    <citrus:dispatching-endpoint-adapter id="dispatchingEndpointAdapter"
             mapping-key-extractor="mappingKeyExtractor"
             mapping-strategy="mappingStrategy"/>
    
    
    <bean id="mappingKeyExtractor" class="com.consol.citrus.endpoint.adapter.mapping.HeaderMappingKeyExtractor">
        <property name="headerName" value="#{T(com.consol.citrus.http.message.HttpMessageHeaders).HTTP_REQUEST_URI}"/>
    </bean>
    
    <bean id="mappingStrategy"
      class="com.consol.citrus.endpoint.adapter.mapping.SimpleMappingStrategy">
        <property name="adapterMappings">
          <map>
              <entry key="/callback" value-ref="responseAdapter"/>
          </map>
        </property>
    </bean>
    
    <citrus:static-response-adapter id="responseAdapter">
    </citrus:static-response-adapter>
    

    然后,我使用Java DSL代码,它应该在回调时接收预期的有效负载

    receive(receiveCallbackMockService)
        .payload(new ClassPathResource("/async/callbackExpectedRequest01.xml"));
    

    但我在执行测试时遇到这样的异常:

    14:25:43,516 ERROR        citrus.Citrus| TEST FAILED HELLO_ASYNC_01: output 039 <com.mycompany.myproject> Nested exception is:
    com.consol.citrus.exceptions.CitrusRuntimeException: Unable to create endpoint for static endpoint adapter type 'class com.consol.citrus.endpoint.adapter.RequestDispatchingEndpoint
    Adapter'
            at com.consol.citrus.endpoint.adapter.StaticEndpointAdapter.getEndpoint(StaticEndpointAdapter.java:35)
            at com.consol.citrus.server.AbstractServer.createConsumer(AbstractServer.java:200)
            at com.consol.citrus.actions.ReceiveMessageAction.receive(ReceiveMessageAction.java:146)
            at com.consol.citrus.actions.ReceiveMessageAction.doExecute(ReceiveMessageAction.java:125)
            at com.consol.citrus.actions.AbstractTestAction.execute(AbstractTestAction.java:42)
            at com.consol.citrus.dsl.actions.DelegatingTestAction.doExecute(DelegatingTestAction.java:54)
            at com.consol.citrus.actions.AbstractTestAction.execute(AbstractTestAction.java:42)
            at com.consol.citrus.TestCase.executeAction(TestCase.java:214)
            at com.consol.citrus.TestCase.doExecute(TestCase.java:142)
            at com.consol.citrus.actions.AbstractTestAction.execute(AbstractTestAction.java:42)
            at com.consol.citrus.Citrus.run(Citrus.java:254)
            at com.consol.citrus.dsl.testng.TestNGCitrusTest.invokeTestMethod(TestNGCitrusTest.java:124)
            at com.consol.citrus.dsl.testng.TestNGCitrusTestDesigner.invokeTestMethod(TestNGCitrusTestDesigner.java:73)
            at com.consol.citrus.dsl.testng.TestNGCitrusTest.run(TestNGCitrusTest.java:100)
            at com.consol.citrus.dsl.testng.TestNGCitrusTest.run(TestNGCitrusTest.java:58)
            at org.testng.internal.MethodInvocationHelper.invokeHookable(MethodInvocationHelper.java:209)
            at org.testng.internal.Invoker.invokeMethod(Invoker.java:639)
            at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:820)
            at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1128)
            at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:129)
            at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:112)
            at org.testng.TestRunner.privateRun(TestRunner.java:782)
            at org.testng.TestRunner.run(TestRunner.java:632)
            at org.testng.SuiteRunner.runTest(SuiteRunner.java:366)
            at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:361)
            at org.testng.SuiteRunner.privateRun(SuiteRunner.java:319)
            at org.testng.SuiteRunner.run(SuiteRunner.java:268)
            at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
            at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
            at org.testng.TestNG.runSuitesSequentially(TestNG.java:1244)
            at org.testng.TestNG.runSuitesLocally(TestNG.java:1169)
            at org.testng.TestNG.run(TestNG.java:1064)
            at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:132)
            at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.executeMulti(TestNGDirectoryTestSuite.java:224)
            at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.execute(TestNGDirectoryTestSuite.java:113)
            at org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:146)
            at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:286)
            at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:240)
            at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:121)
    

    在异步测试场景中,我应该如何配置Citrus HTTP模拟服务器以接收回调请求(并使用预期的请求负载对其进行验证)?

    2 回复  |  直到 9 年前
        1
  •  0
  •   Christoph Deppisch    9 年前

    您同时在Citrus服务器组件上使用静态响应适配器和receive()操作。这不起作用。静态响应适配器将始终跳转,测试中的接收操作永远不会收到任何请求。

    如果要在测试用例中接收来自该服务器组件的请求,请将调度响应适配器与静态响应适配器一起移除。

        2
  •  0
  •   supertramp    9 年前

    只是找时间分享我的解决方案。首先,有一个帖子( http://citrus.895196.n3.nabble.com/Citrus-to-act-as-a-mock-server-td4023066.html )告诉我们,“您需要的是一个独立的模拟器,它等待传入请求并发送预定义的响应消息。这不是Citrus作为测试框架的主要重点”。但我找到了一个解决办法:

    1) 使用全局变量作为标志,告诉我们异步请求是否从SUT到达:

    Spring上下文:

    <bean id="globalVariables" class="com.consol.citrus.variables.GlobalVariables"></bean>
    

    Java代码:

    @Autowired
    private GlobalVariables globalVariables
    

    在开始等待SUT异步回调请求之前,设置变量(标志)

    globalVariables.getVariables().put("SUTcallbackStatus", "waiting");
    

    2) 延伸 IteratingConditionExpression -推翻 evaluate 方法如下:

    @Override
    public boolean evaluate(int index, TestContext context) {
    
        if(index > threshold){
            testToFail.fail("The async message didn't arrived to the mock server.");
            return false;
        }
    
        if(globalVariables.getVariables().get("SUTcallbackStatus").equals("received")){
            return false;
        }
    
        return true;
    }
    

    这个 testToFail threshold 上述代码中的变量应在测试类中设置:

    myIteratingConditionExpression.setThreshold(50);
    myIteratingConditionExpression.setTestToFail(this);
    

    它允许您控制测试等待响应的时间( 门槛 * 0.5 sec),并允许您指向测试,如果在假设的时间段内未收到回调响应,则测试将失败。

    3) 延伸 StaticResponseEndpointAdapter -重写下面的方法

    @Override
    public Message handleMessageInternal(Message message) {
    
        globalVariables.getVariables().put("SUTcallbackStatus", "received");
        return super.handleMessageInternal(message);
    }
    

    并将此适配器用作模拟服务适配器:

    <citrus-http:server id="asyncResponseMockService"
      port="${server.callback.port}"
      auto-start="true"
      timeout="10000"
      endpoint-adapter="myResponseAdapter" />
    

    4) 然后,在测试类中-要开始等待异步回调请求-只需使用 iterate 使用自定义迭代条件表达式的操作:

    iterate(sleep(0.5)).condition(myIteratingConditionExpression);
    

    这为我做的工作:)

    推荐文章