Package org.mule.munit

Source Code of org.mule.munit.MockModule

/*
* Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
* The software in this package is published under the terms of the CPAL v1.0
* license, a copy of which has been included with this distribution in the
* LICENSE.txt file.
*/
/**
* This file was automatically generated by the Mule Development Kit
*/
package org.mule.munit;

import static org.mule.modules.interceptor.processors.MessageProcessorId.getName;
import static org.mule.modules.interceptor.processors.MessageProcessorId.getNamespace;
import static org.mule.munit.common.MunitCore.buildMuleStackTrace;
import org.mule.DefaultMuleMessage;
import org.mule.api.DefaultMuleException;
import org.mule.api.MuleContext;
import org.mule.api.MuleEvent;
import org.mule.api.MuleException;
import org.mule.api.MuleMessage;
import org.mule.api.NestedProcessor;
import org.mule.api.annotations.Module;
import org.mule.api.annotations.Processor;
import org.mule.api.annotations.param.Optional;
import org.mule.api.context.MuleContextAware;
import org.mule.api.processor.MessageProcessor;
import org.mule.munit.common.mocking.EndpointMocker;
import org.mule.munit.common.mocking.MessageProcessorMocker;
import org.mule.munit.common.mocking.MunitMuleMessageTransformer;
import org.mule.munit.common.mocking.MunitSpy;
import org.mule.munit.common.mocking.MunitVerifier;
import org.mule.munit.common.mocking.NotDefinedPayload;
import org.mule.munit.common.mocking.SpyProcess;
import org.mule.transformer.AbstractMessageTransformer;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

/**
* <p>
* Munit module for mocking message processors.
* <p/>
* </p>
*
* @author Mulesoft Inc.
* @since 3.3.2
*/
@Module(name = "mock", schemaVersion = "3.4", friendlyName = "Mock")
public class MockModule implements MuleContextAware
{

    private MuleContext muleContext;


    /**
     * <p>Define what the mock must return on a message processor call.</p>
     * <p/>
     * <p>If the message processor doesn't return any value then there is no need to define an expect.</p>
     * <p/>
     * <p>You can define the message processor parameters in the same order they appear in the API documentation. In
     * order to define the behaviour on that particular case.</p>
     * <p/>
     * {@sample.xml ../../../doc/mock-connector.xml.sample mock:expect}
     *
     * @param messageProcessor     Message processor name.
     * @param thenReturn           Expected return value.
     * @param withAttributes       Message processor parameters.
     * @param thenApplyTransformer Custom transformer to apply to the message
     */
    @Processor
    public void when(String messageProcessor,
                     @Optional List<Attribute> withAttributes,
                     @Optional MunitMuleMessage thenReturn,
                     @Optional final Object thenApplyTransformer)
    {
        if (thenApplyTransformer != null && thenApplyTransformer instanceof AbstractMessageTransformer)
        {
            mocker().when(getName(messageProcessor))
                    .ofNamespace(getNamespace(messageProcessor))
                    .withAttributes(createAttributes(withAttributes))
                    .thenApply(new MunitMuleMessageTransformer((AbstractMessageTransformer) thenApplyTransformer));
        }
        else
        {
            MunitMuleMessage munitMuleMessage = thenReturn == null ? new MunitMuleMessage() : thenReturn;

            mocker().when(getName(messageProcessor))
                    .ofNamespace(getNamespace(messageProcessor))
                    .withAttributes(createAttributes(withAttributes))
                    .thenReturn(createMuleMessageFrom(munitMuleMessage.getPayload(),
                                                      munitMuleMessage.getInboundProperties(),
                                                      munitMuleMessage.getOutboundProperties(),
                                                      munitMuleMessage.getSessionProperties(),
                                                      munitMuleMessage.getInvocationProperties()));
        }
    }

    /**
     * <p>Define what the mock must return on a message processor call.</p>
     * <p/>
     * <p>If the message processor doesn't return any value then there is no need to define an expect.</p>
     * <p/>
     * <p>You can define the message processor parameters in the same order they appear in the API documentation. In
     * order to define the behaviour on that particular case.</p>
     * <p/>
     * {@sample.xml ../../../doc/mock-connector.xml.sample mock:spy}
     *
     * @param messageProcessor     Message processor name.
     * @param withAttributes       Sets of attributes to narrow-down a specific message processor
     * @param assertionsBeforeCall Expected return value.
     * @param assertionsAfterCall  Message processor parameters.
     */
    @Processor
    public void spy(String messageProcessor,
                    @Optional List<Attribute> withAttributes,
                    @Optional List<NestedProcessor> assertionsBeforeCall,
                    @Optional List<NestedProcessor> assertionsAfterCall)
    {
        spy().spyMessageProcessor(getName(messageProcessor))
                .ofNamespace(getNamespace(messageProcessor))
                .withAttributes(createAttributes(withAttributes))
                .before(createSpyAssertion(createMessageProcessorsFrom(assertionsBeforeCall)))
                .after(createSpyAssertion(createMessageProcessorsFrom(assertionsAfterCall)));
    }

    /**
     * <p>Expect to throw an exception when message processor is called. </p>
     * <p/>
     * {@sample.xml ../../../doc/mock-connector.xml.sample mock:expectFail}
     *
     * @param exception      Java Exception full qualified name.
     * @param whenCalling    Message processor name.
     * @param withAttributes list of expected attributes
     */
    @Processor
    public void throwAn(Throwable exception, String whenCalling,
                        @Optional List<Attribute> withAttributes)
    {

        mocker().when(getName(whenCalling))
                .ofNamespace(getNamespace(whenCalling))
                .withAttributes(createAttributes(withAttributes))
                .thenThrow(exception);

    }


    /**
     * Check that the message processor was called with some specified parameters
     * <p/>
     * {@sample.xml ../../../doc/mock-connector.xml.sample mock:verifyCall}
     *
     * @param messageProcessor Message processor Id
     * @param attributes       Message processor parameters.
     * @param times            Number of times the message processor has to be called
     * @param atLeast          Number of time the message processor has to be called at least.
     * @param atMost           Number of times the message processor has to be called at most.
     */
    @Processor
    public void verifyCall(String messageProcessor, @Optional List<Attribute> attributes,
                           @Optional Integer times,
                           @Optional Integer atLeast, @Optional Integer atMost)
    {

        try
        {
            MunitVerifier mockVerifier =
                    verifier().verifyCallOfMessageProcessor(getName(messageProcessor))
                            .ofNamespace(getNamespace(messageProcessor))
                            .withAttributes(createAttributes(attributes));

            if (times != null)
            {
                mockVerifier.times(times);

            }
            else if (atLeast != null)
            {
                mockVerifier.atLeast(atLeast);
            }
            else if (atMost != null)
            {
                mockVerifier.atMost(atMost);
            }
            else
            {
                mockVerifier.atLeastOnce();
            }

        }
        catch (AssertionError error)
        {
            AssertionError assertionException = new AssertionError(getMessage(error, "Verify Processor Failed"));
            assertionException.setStackTrace(buildMuleStackTrace(muleContext).toArray(new StackTraceElement[] {}));

            throw assertionException;
        }

    }


    /**
     * Reset mock behaviour
     * <p/>
     * {@sample.xml ../../../doc/mock-connector.xml.sample mock:outboundEndpoint}
     *
     * @param address                    the address
     * @param exception                  in case it fails
     * @param returnPayload              the Return Payload
     * @param thenApplyTransformer       custom transformer to be applied to the message
     * @param returnInboundProperties    inbound properties
     * @param returnInvocationProperties invocation properties
     * @param returnSessionProperties    invocation session properties
     * @param returnOutboundProperties   oubound properties
     * @param assertions                 assertions
     */
    @Processor
    public void outboundEndpoint(String address,
                                 @Optional Object returnPayload,
                                 @Optional DefaultMuleException exception,
                                 @Optional Object thenApplyTransformer,
                                 @Optional Map<String, Object> returnInvocationProperties,
                                 @Optional Map<String, Object> returnInboundProperties,
                                 @Optional Map<String, Object> returnSessionProperties,
                                 @Optional Map<String, Object> returnOutboundProperties,
                                 @Optional List<NestedProcessor> assertions)
    {
        if (thenApplyTransformer != null && thenApplyTransformer instanceof AbstractMessageTransformer)
        {
            endpointMocker().whenEndpointWithAddress(address)
                    .withIncomingMessageSatisfying(createSpyAssertion(createMessageProcessorsFrom(assertions)))
                    .thenApply(new MunitMuleMessageTransformer((AbstractMessageTransformer) thenApplyTransformer));
        }
        else
        {

            if (exception != null)
            {

                endpointMocker().whenEndpointWithAddress(address)
                        .withIncomingMessageSatisfying(createSpyAssertion(createMessageProcessorsFrom(assertions)))
                        .thenThrow(exception);
            }
            else
            {
                endpointMocker().whenEndpointWithAddress(address)
                        .withIncomingMessageSatisfying(createSpyAssertion(createMessageProcessorsFrom(assertions)))
                        .thenReturn(createMuleMessageFrom(returnPayload,
                                                          returnInboundProperties,
                                                          returnOutboundProperties,
                                                          returnSessionProperties,
                                                          returnInvocationProperties));
            }
        }
    }


    @Override
    public void setMuleContext(MuleContext muleContext)
    {
        this.muleContext = muleContext;
    }


    private MuleMessage createMuleMessageFrom(Object payload,
                                              Map<String, Object> inboundProperties,
                                              Map<String, Object> outboundProperties,
                                              Map<String, Object> sessionProperties,
                                              Map<String, Object> invocationProperties
    )
    {
        Object definedPayload = payload;
        if (payload == null)
        {
            definedPayload = NotDefinedPayload.getInstance();
        }
        DefaultMuleMessage message = new DefaultMuleMessage(definedPayload, muleContext);

        if (inboundProperties != null)
        {
            for (String property : inboundProperties.keySet())
            {
                message.setInboundProperty(property, inboundProperties.get(property));
            }
        }

        if (outboundProperties != null)
        {
            for (String property : outboundProperties.keySet())
            {
                message.setOutboundProperty(property, outboundProperties.get(property));
            }
        }

        if (invocationProperties != null)
        {
            for (String property : invocationProperties.keySet())
            {
                message.setInvocationProperty(property, invocationProperties.get(property));
            }
        }

        // TODO: how we can set the session properties?
        //        if ( sessionProperties != null ){
        //            for (String property : sessionProperties.keySet() ){
        //                message.setProperty(property, sessionProperties.get(property), PropertyScope.SESSION);
        //            }
        //        }
        return message;
    }


    private List<MessageProcessor> createMessageProcessorsFrom(List<NestedProcessor> assertions)
    {
        if (assertions == null)
        {
            return null;
        }

        final List<MessageProcessor> mps = new ArrayList<MessageProcessor>();
        for (NestedProcessor nestedProcessor : assertions)
        {
            mps.add(new NestedMessageProcessor(nestedProcessor));
        }

        return mps;
    }

    private Map<String, Object> createAttributes(List<Attribute> attributes)
    {
        Map<String, Object> attrs = new HashMap<String, Object>();
        if (attributes == null)
        {
            return attrs;
        }

        for (Attribute attr : attributes)
        {
            attrs.put(attr.getName(), attr.getWhereValue());
        }

        return attrs;
    }


    private List<SpyProcess> createSpyAssertion(final List<MessageProcessor> messageProcessorsFrom)
    {
        List<SpyProcess> mps = new ArrayList<SpyProcess>(1);
        if (messageProcessorsFrom != null)
        {
            mps.add(createSpy(messageProcessorsFrom));
        }
        return mps;
    }

    protected SpyProcess createSpy(final List<MessageProcessor> messageProcessorsFrom)
    {
        return new SpyProcess()
        {

            @Override
            public void spy(MuleEvent event) throws MuleException
            {
                for (MessageProcessor mp : messageProcessorsFrom)
                {
                    mp.process(event);
                }
            }
        };
    }


    protected MessageProcessorMocker mocker()
    {
        return new MessageProcessorMocker(muleContext);
    }

    protected EndpointMocker endpointMocker()
    {
        return new EndpointMocker(muleContext);
    }

    protected MunitVerifier verifier()
    {
        return new MunitVerifier(muleContext);
    }

    protected MunitSpy spy()
    {
        return new MunitSpy(muleContext);
    }

    private String getMessage(AssertionError error, String defaultValue)
    {
        String message = error.getMessage();
        if (StringUtils.isEmpty(message))
        {
            return defaultValue;
        }
        return message;
    }

}
TOP

Related Classes of org.mule.munit.MockModule

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.