Citrus Framework异步HTTP测试场景

时间:2016-11-04 14:17:03

标签: asynchronous integration-testing citrus-framework

我有异步测试场景。我打电话给我的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 Mock Server以接收回调请求(并使用预期的请求有效负载进行验证)?

2 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

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

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

春天背景:

<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;
}

上面代码中的testToFailthreshold变量应该从Test类设置:

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

它允许您控制测试应等待响应的时间(threshold * 0.5秒)并允许您指向测试,如果未在接收回调响应的情况下该测试应该失败假设期间。

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)然后,在您的测试类中 - 开始等待异步回调请求 - 只需对自定义iteratingConditionExpression使用iterate操作:

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

这为我做的工作:)