简体   繁体   English

如何使用MUnit在Mule Flow中模拟Java组件

[英]How to mock a Java component within Mule Flow using MUnit

I am trying to Unit test one of my sub-flows using MUnit, I need to mock out a custom Java component but I am unable to do so. 我试图使用MUnit对我的子流之一进行单元测试,我需要模拟出一个自定义Java组件,但是我无法这样做。

My sub-flow reads as below 我的子流程如下

被测子流

<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"/>
    <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}"/>
    <!-- <component class="nz.co.mightyriver.creditreport.component.ArchiveOutputComponent" doc:name="Archive"/> -->
    <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="nz.co.mightyriver.creditreport.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>

This is my failing unit test 这是我失败的单元测试

@Test
public void givenAValidPayload_whenFlowIsInvoked_itShouldSendPayloadToDestinationSFTPOnlyOnce() throws Exception {
    destinationSFTP.thenReturnSameEvent();
    sourceArchiveSFTP.thenReturnSameEvent();
    deleteProcessedFileComponent.thenReturnSameEvent();
    successEmail.thenReturnSameEvent();


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

    runFlow(PROCESS_CSV_FLOW, testEvent);

    verifyCallOfMessageProcessor("outbound-endpoint")
            .ofNamespace("sftp")
            .withAttributes(attribute("name").ofNamespace("doc").withValue("DestinationSFTP"))
            .times(1);

}

My attempt at mocking out the component 我尝试模拟该组件

deleteProcessedFileComponent = whenMessageProcessor("component")
            .withAttributes(attribute("name").ofNamespace("doc").withValue("Delete Read File"));

I have tried a few variations and none have worked, I am guessing a component is not a MessageProcessor 我尝试了一些变体,但都没有奏效,我猜组件不是MessageProcessor

The exception I get is as follows 我得到的异常如下

org.mule.api.lifecycle.InitialisationException: Component has not been initialized properly, no flow constuct.
at org.mule.component.AbstractComponent.initialise(AbstractComponent.java:218)
at org.mule.processor.chain.AbstractMessageProcessorChain.initialise(AbstractMessageProcessorChain.java:80)
at org.mule.processor.chain.AbstractMessageProcessorChain$$FastClassByCGLIB$$38c17d88.invoke(<generated>)
at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191)
at org.mule.munit.common.mp.WrapperMunitMessageProcessorInterceptor.invokeSuper(WrapperMunitMessageProcessorInterceptor.java:71)
at org.mule.munit.common.mp.WrapperMunitMessageProcessorInterceptor.invokeSuper(WrapperMunitMessageProcessorInterceptor.java:63)
at org.mule.munit.common.mp.WrapperMunitMessageProcessorInterceptor.intercept(WrapperMunitMessageProcessorInterceptor.java:49)
at org.mule.processor.chain.SubflowInterceptingChainLifecycleWrapper$$EnhancerByMUNIT$$c8ca2508.initialise(<generated>)
at org.mule.munit.runner.functional.FunctionalMunitSuite.initialiseSubFlow(FunctionalMunitSuite.java:269)
at org.mule.munit.runner.functional.FunctionalMunitSuite.runFlow(FunctionalMunitSuite.java:259)
at nz.co.mightyriver.ProcessCsvTest.givenAValidPayload_whenFlowIsInvoked_itShouldSendPayloadToDestinationSFTPOnlyOnce(ProcessCsvTest.java:62)
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)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:69)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:48)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.ParentRunner.run(ParentRunner.java:292)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

So there is no problem with your mock it actually work perfectly. 因此,您的模拟游戏没有问题,它实际上可以完美运行。 The problem is with Mule and a little bit with MUnit. 问题出在Mule上,而MUnit则在一点点。

Short answer, there is no fix for that right now. 简短的答案,目前没有解决方案。 There is a workaround though! 虽然有一种解决方法!

Create a new xml (as to keep it separate from your production code) Add flow (not a sub-flow) to that new xml. 创建一个新的xml(以使其与生产代码分开),向该新的xml添加流(而不是子流)。 In the flow you just added do a flow-ref to your sub-flow. 在刚刚添加的流中,对子流进行流引用。 From you test, instead of doing runFlow(PROCESS_CSV_FLOW), do runFlow("the_flow_you_created"). 通过测试,您可以执行runFlow(“ the_flow_you_created”),而不是执行runFlow(PROCESS_CSV_FLOW)。

The longer answer is: 更长的答案是:

The sub-flows are not real flows, they don't even share a parent class. 子流不是真正的流,它们甚至不共享父类。 Thus they behave a little bit different. 因此,它们的行为略有不同。 MUnit does some stuff to make that fact transparent to the user. MUnit做一些事情使事实对用户透明。

As it turns out we are not making enough, I'll create a jira in the MUnit project to tackle that issue. 事实证明,我们做的还不够,我将在MUnit项目中创建一个jira来解决该问题。 But hopefully you should be able to keep testing. 但是希望您应该能够继续进行测试。

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

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