2015-04-27 7 views
2

Я пытаюсь написать тесты MUnit для потоков Mule. Я хочу написать тест для ниже потокаMUnit тестирование потока с помощью сборщика-агрегатора

Complete mule flow

<flow name="DownloadFTPFileIntoLocalFlow" processingStrategy="synchronous" tracking:enable-default-events="true"> 
    <quartz:inbound-endpoint jobName="Source-File-Scheduler" cronExpression="${source.pollingfrequency}" startDelay="10000" responseTimeout="10000" doc:name="Quartz"> 
     <quartz:endpoint-polling-job> 
      <quartz:job-endpoint ref="InputSFTPEndpoint"/> 
     </quartz:endpoint-polling-job> 
    </quartz:inbound-endpoint> 
    <logger message="DownloadFTPFileIntoLocalFlow #[payload.getClass().getName()]" level="INFO" doc:name="Logger"/> 
    <set-property propertyName="MULE_CORRELATION_GROUP_SIZE" value="#[java.lang.Integer.MAX_VALUE]" doc:name="GroupsizeForExceptionAggregator"/> 
    <set-property propertyName="MULE_CORRELATION_ID" value="#[java.util.UUID.randomUUID().toString()]" doc:name="corelationIdForExceptionAggregator"/> 
    <set-variable variableName="originalPayload" value="#[payload]" doc:name="originalPayload"/> 
    <byte-array-to-object-transformer doc:name="Byte Array to Object"/> 
    <flow-ref name="ProcessCSVFlow" doc:name="ProcessCSVFlow" /> 
    <exception-strategy ref="Default_Exception_Strategy" doc:name="DownloadFTPFileIntoLocalFlow Strategy"/> 
</flow> 


<sub-flow name="ProcessCSVFlow" tracking:enable-default-events="true"> 
    <transformer ref="enrichWithHeaderAndEndOfFileTransformer" doc:name="headerAndEOFEnricher" /> 
    <set-variable variableName="outputfilename" value="#['Mercury'+server.dateTime.year+server.dateTime.month+server.dateTime.dayOfMonth+server.dateTime.hours+server.dateTime.minutes+server.dateTime.seconds+'.csv']" doc:name="outputfilename"/> 
    <!-- <set-variable variableName="outputfilename" value="#['Mercury'+server.dateTime.year+':'+server.dateTime.month+':'+server.dateTime.dayOfMonth+'::'+server.dateTime.hours+':'+server.dateTime.minutes+':'+server.dateTime.seconds+'.csv']" doc:name="outputfilename"/> --> 
    <sftp:outbound-endpoint exchange-pattern="one-way" connector-ref="DestinationSFTP" host="${destination.host}" port="22" responseTimeout="10000" doc:name="DestinationSFTP" 
    outputPattern="#[outputfilename]" path="${destination.path}" user="${destination.username}" password="${destination.password}"/> 
    <gzip-compress-transformer/> 
    <sftp:outbound-endpoint exchange-pattern="one-way" connector-ref="InputSFTP" host="${source.host}" port="22" responseTimeout="10000" doc:name="SourceArchiveSFTP" 
    outputPattern="#[outputfilename].gzip" path="Archive" user="${source.username}" password="${source.password}"/> 
    <component doc:name="Delete Read File"> 
     <singleton-object class="component.DeleteProcessedFileComponent"> 
      <property key="host" value="${source.host}"/> 
      <property key="username" value="${source.username}"/> 
      <property key="password" value="${source.password}"/> 
      <property key="workingDirectory" value="${source.path}"/> 
     </singleton-object> 
    </component> 
    <parse-template location="successmessagetemplate.txt" doc:name="Success Template"/> 
    <smtp:outbound-endpoint host="${smtp.host}" port="${smtp.port}" user="${smtp.from.address}" password="${smtp.from.password}" 
          to="${smtp.to.address}" from="${smtp.from.address}" subject="${mail.success.subject}" responseTimeout="10000" 
          doc:name="SuccessEmail" connector-ref="Gmail"/> 
    <logger message="Process completed successfully" level="INFO" doc:name="Logger"/> 
</sub-flow> 

блок обработки исключений

<catch-exception-strategy name="Default_Exception_Strategy"> 
    <flow-ref name="ExceptionHandlingSubflow" doc:name="ExceptionHandlingSubflow"/> 
</catch-exception-strategy> 

<sub-flow name="ExceptionHandlingSubflow" tracking:enable-default-events="true"> 
    <collection-aggregator timeout="60000" failOnTimeout="false" doc:name="Exception Aggregator"/> 
    <logger message="Exception has occured Payload is #[payload] and Message is #[message]" level="ERROR" doc:name="Logger"/> 
    <parse-template location="errormessagetemplate.txt" doc:name="Error Template"/> 
    <smtp:outbound-endpoint host="${smtp.host}" port="${smtp.port}" user="${smtp.from.address}" password="${smtp.from.password}" 
          to="${smtp.to.address}" from="${smtp.from.address}" subject="${mail.failure.subject}" responseTimeout="10000" 
          doc:name="ErrorEmail" connector-ref="Gmail"/> 
</sub-flow> 

Интересный бит является исключением суб-поток, особенно коллекция-агрегатор

Мой модульный тест:

@Test 
public void whenMultipleExceptionsOccurInFlow_itShouldSendOnlyOneFailureEmail() throws Exception { 
    whenMessageProcessor("collection-aggregator") 
      .withAttributes(attribute("name").ofNamespace("doc").withValue("Exception Aggregator")).thenReturnSameEvent(); 

    destinationSFTP.thenThrow(new RuntimeException("Dummy Exception destinationSFTP")); 

    MuleEvent testEvent = PropertyEnricher.enrich(testEvent(IOUtils.toInputStream("hello,dummy,payload"))).get(); 

    runFlow("DownloadFTPFileIntoLocalFlow", testEvent); 

    verifyCallOfMessageProcessor("outbound-endpoint").ofNamespace("smtp") 
      .withAttributes(attribute("name").ofNamespace("doc").withValue("ErrorEmail")) 
      .times(1); 
} 

Теперь, если я не издеваюсь над сборщиком сборки, мой тест не проходит, я могу понять, что это сложно, поскольку агрегатор имеет «паузу» внутри него и, следовательно, не является идеальным кандидатом для модульного теста, техническая точка зрения Я хочу понять, что приводит к сбою модульного теста (когда сборщик-агрегатор не издевается).

Мой тест не срабатывает, когда сборщик-агрегатор не издевается.

junit.framework.AssertionFailedError: On smtp:outbound-endpoint.Expected 1 but got 0 calls 
    at junit.framework.Assert.fail(Assert.java:50) 
    at org.mule.munit.common.mocking.MunitVerifier.times(MunitVerifier.java:86) 
    at nz.co.mightyriver.ProcessCsvTest.whenMultipleExceptionsOccurInFlow_itShouldSendOnlyOneFailureEmail(ProcessCsvTest.java:100) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:606) 

ответ

0

Так что я пытался воспроизвести этот вопрос:

Продукция Код

<http:listener-config name="HTTP_Listener_Configuration" host="0.0.0.0" port="9090" doc:name="HTTP Listener Configuration"/> 
    <flow name="stack-munit-and-aggregationFlow"> 
     <http:listener config-ref="HTTP_Listener_Configuration" path="/" doc:name="HTTP"/> 
     <set-payload value="#['lalero_' + new java.util.Date().toString()]" doc:name="Set Payload"/> 
     <flow-ref name="stack-munit-and-aggregationSub_Flow" doc:name="stack-munit-and-aggregationSub_Flow"/> 
     <set-payload doc:name="Set Payload" value="#[payload.toString()]"/> 
    </flow> 
    <sub-flow name="stack-munit-and-aggregationSub_Flow"> 
     <collection-aggregator failOnTimeout="true" doc:name="Collection Aggregator" timeout="10"/> 
    </sub-flow> 

Код проверки

package org.mule.munit; 

import org.junit.Assert; import org.junit.Test; import org.mule.api.MuleEvent; import org.mule.api.MuleException; import org.mule.munit.runner.functional.FunctionalMunitSuite; 

public class TheTest extends FunctionalMunitSuite { 

    @Test 
    public void aTest() throws MuleException, Exception { MuleEvent event = runFlow("stack-munit-and-aggregationFlow", testEvent("")); 

    String payload = (String) event.getMessage().getPayload(); 

    Assert.assertTrue(payload.contains("lalero")); 
    } } 

Если вы отметите этот код Я буду замечать, что я не мок выйдите из сборщика. После нескольких тестов я не смог воспроизвести вашу ошибку.

Я думаю, что проблема может быть в другом месте. Не могли бы вы поделиться своим кодом, чтобы я мог продолжить исследование?

Мир предупреждения, хотя, из-за проблем обнаружены: How to mock a Java component within Mule Flow using MUnit

Вы можете найти проблему, если вы пытаетесь непосредственно протестировать ExceptionHandlingSubFlow суб-потока. Но поскольку вы не делали этого в своем примере кода, я не думаю, что эти два связаны друг с другом.

Cheers!

+0

Большое спасибо за то, что вы так заинтересовались, обновили мой вопрос с запрошенными деталями. Также я получил исключение, напечатанное неправильно в прошлый раз (не уверен, как я удалился), так что теперь мое утверждение терпит неудачу, если агрегирующий маршрутизатор не издевались. – Sudarshan

+0

Привет, Для того, что я вижу, кажется, что ошибка в потоке с агрегатором MP (который BTW вы не отправляли). В любом случае я предлагаю вам попробовать повторить тест MUnit, где вы можете отлаживать потоки мула. Если он терпит неудачу, когда он не издевается (агрегация), вероятно, что-то в полезной нагрузке, достигающей этого MP, не является ожидаемым (я считаю исключение). Я не вижу на данный момент ничего, что указывает на ошибку MUnit :( – Dds

+0

Спасибо, я добавил блок обработки исключений, который использует сборщик-агрегатор, было бы неплохо, если бы вы могли посмотреть. – Sudarshan