1

I'm writing a test suite (using Munit) for a Mule application that is processing new data coming from an instance of Magento. One of my flows is polling Magento for new customers and the message it receives is of type: com.magento.api.CustomerCustomerEntity

I'm wondering how I'd mock this so that in my test case, when the Magento message processor is called I can return a payload of the same type and make the appropriate assertations?

Currently my Munit test looks as follows:

<mock:config name="mock_MagentoToSalesforce" doc:name="Mock configuration"/>
<spring:beans>
    <spring:import resource="classpath:MagentoToSalesforce.xml"/>
    <spring:bean id="myBean" name="myBean" class="com.magento.api.CustomerCustomerEntity">
        <spring:property name="email" value="test@test.com"/>
    </spring:bean>
</spring:beans>

<munit:test name="MagentoToSalesforce-test-getCustomersFlowTest" description="Test">
    <mock:when config-ref="mock_MagentoToSalesforce" messageProcessor=".*:.*" doc:name="Mock">
        <mock:with-attributes>
            <mock:with-attribute whereValue-ref="#[string:Get New Customers]" name="doc:name"/>
        </mock:with-attributes>
        <mock:then-return payload-ref="#[app.registry.myBean]"/>
    </mock:when>
    <flow-ref name="getCustomers" doc:name="Flow-ref to getCustomers"/>
</munit:test>

And the flow I'm trying to test is:

<flow name="getCustomers" processingStrategy="synchronous">
    <poll doc:name="Poll">
        <fixed-frequency-scheduler frequency="30" timeUnit="SECONDS"/>
        <watermark variable="watermark" default-expression="#[new org.mule.el.datetime.DateTime().plusYears(-30)]" update-expression="#[new org.mule.el.datetime.DateTime().plusYears(-0)]" selector-expression="#[new org.mule.el.datetime.DateTime(payload.created_at, 'yyyy-MM-dd HH:mm:ss')]"/>
        <magento:list-customers config-ref="Magento" filter="dsql:SELECT confirmation,created_at,created_in,customer_id,dob,email,firstname,group_id,increment_id,lastname,middlename,password_hash,prefix,store_id,suffix,taxvat,updated_at,website_id FROM CustomerCustomerEntity WHERE updated_at &gt; '#[flowVars.watermark]'" doc:name="Get New Customers"/>
    </poll>
    <foreach doc:name="For Each">
        <data-mapper:transform config-ref="MagentoCustomer_To_SalesforceContact" doc:name="Map Customer to SFDC Contact">
            <data-mapper:input-arguments>
                <data-mapper:input-argument key="ContactSource">Magento</data-mapper:input-argument>
            </data-mapper:input-arguments>
        </data-mapper:transform>
        <flow-ref name="upsertSalesforceContactFlow" doc:name="upsertSalesforceContactFlow"/>
    </foreach>
</flow>

Update following Ryan's answer:

Changed the expression to return a payload of #[ent = new com.magento.api.CustomerCustomerEntity(); ent.setEmail('test@test.com'); return [ent];] - note, changed the method to setEmail to match the documentation here. The error I get with this is:

ERROR 2015-06-22 09:58:34,719 [main] org.mule.exception.DefaultMessagingExceptionStrategy: 
********************************************************************************
Message               : Object "org.mule.transport.NullPayload" not of correct type. It must be of type "{interface java.lang.Iterable,interface java.util.Iterator,interface org.mule.routing.MessageSequence,interface java.util.Collection}" (java.lang.IllegalArgumentException). Message payload is of type: NullPayload
Code                  : MULE_ERROR--2
--------------------------------------------------------------------------------
Exception stack is:
1. Object "org.mule.transport.NullPayload" not of correct type. It must be of type "{interface java.lang.Iterable,interface java.util.Iterator,interface org.mule.routing.MessageSequence,interface java.util.Collection}" (java.lang.IllegalArgumentException)
  org.mule.util.collection.EventToMessageSequenceSplittingStrategy:64 (null)
2. Object "org.mule.transport.NullPayload" not of correct type. It must be of type "{interface java.lang.Iterable,interface java.util.Iterator,interface org.mule.routing.MessageSequence,interface java.util.Collection}" (java.lang.IllegalArgumentException). Message payload is of type: NullPayload (org.mule.api.MessagingException)
  org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor:32 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/MessagingException.html)
--------------------------------------------------------------------------------
Root Exception stack trace:
java.lang.IllegalArgumentException: Object "org.mule.transport.NullPayload" not of correct type. It must be of type "{interface java.lang.Iterable,interface java.util.Iterator,interface org.mule.routing.MessageSequence,interface java.util.Collection}"
    at org.mule.util.collection.EventToMessageSequenceSplittingStrategy.split(EventToMessageSequenceSplittingStrategy.java:64)
    at org.mule.util.collection.EventToMessageSequenceSplittingStrategy.split(EventToMessageSequenceSplittingStrategy.java:25)
    at org.mule.routing.CollectionSplitter.splitMessageIntoSequence(CollectionSplitter.java:29)
    + 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
********************************************************************************
danw
  • 1,608
  • 4
  • 29
  • 48

1 Answers1

1

One way is to build up the object yourself using the constructor or properties/setters.

From the docs: http://mulesoft.github.io/magento-connector/2.1.2/java/com/magento/api/CustomerCustomerEntity.html

<mock:then-return payload-ref="#[ent = new com.magento.api.CustomerCustomerEntity(); ent.email('test@test.com'); return ent;]"/>

You can also create these objects aS reusable spring beans and reference them from MEL.

    <bean class="com.magento.api.CustomerCustomerEntity" id="myEntityWithEmail">
            <property name="email" value="test@test.com" />
    </bean>

    <mock:then-return payload-ref="#[app.registry.myEntityWithEmail]"/>

After your update I can see that you sre using a foreach which expects a collection or iterable. YOu can return a collection of you custom object simply in MEL using: [] for example:

#[ent = new com.magento.api.CustomerCustomerEntity(); ent.email('test@test.com'); return [ent];]

More on MEL here: https://developer.mulesoft.com/docs/display/current/Mule+Expression+Language+MEL

Or again you can use Spring to return a list:

<util:list id="entities">
    <ref bean="myEntityWithEmail" />
</util:list>
Ryan Carter
  • 11,441
  • 2
  • 20
  • 27
  • Hi Ryan, thanks for the answer. I've given the second option a go and still no luck. The error I'm seeing is: `Object "org.mule.transport.NullPayload" not of correct type. It must be of type "{interface java.lang.Iterable,interface java.util.Iterator,interface org.mule.routing.MessageSequence,interface java.util.Collection}" (java.lang.IllegalArgumentException). Message payload is of type: NullPayload`. I've updated my original question with the new test and the flow I'm trying to test. Any thoughts? – danw Jun 21 '15 at 13:04
  • Also, when I tried the first option, the error I got was along the lines of: `Error: unable to resolve method: com.magento.api.CustomerCustomerEntity.email(java.lang.String) [arglength=1]`. – danw Jun 21 '15 at 13:08
  • Updated my answer.foreach expects a collection or iterable etc. So return a collection: #[ent = new com.magento.api.CustomerCustomerEntity(); ent.email('test@test.com'); return [ent];] – Ryan Carter Jun 21 '15 at 21:51
  • I've given that a go (see updated answer) and still get a similar error. If possible, would you be able to show how to return a list using the spring approach? Thanks again for your help. – danw Jun 22 '15 at 09:02