Thứ Sáu, 22 tháng 4, 2016

Verify Message Processor

Verify Message Processor

Overview

The Verify feature provided by MUnit allows you to define verifications in order to validate a message processor’s calls.
For example, you can validate if a specific message processor has been called with a particular set of attributes a specific number of times.

Defining Verifications

When defining a verification, we are telling MUnit to fail a test if the verification is not successful.
You can define verifications over any message processor, even if you haven’t created a mock for it.
For the purposes of this document, we assume we are testing the following Mule code:
Test code

         
      
1
2
3
<flow name="exampleFlow">
  <set-payload value="#['real_payload']" doc:name="Real Set Payload"/>
</flow>

Defining Message Processor To Verify

When defining a verify, we make use of the verify-call message processor.
<mock:verify-call messageProcessor="mule:set-payload" times="1"/>
Attribute Name Description
messageProcessor
Describes which message processor we want to mock. The description takes the form {name-space}:{message-processor-name}. It supports regular expressions.
times
(Default = 1.) Defines the verification as successful if the message processor was called N and only N number of times.
atLeast
Defines the verification as successful if the message processor was called a minimum of N number of times.
atMost
Defines the verification as successful if the message processor was called maximum of N number of times.
By default, the verify-call message processor assumes times=1 if no value is specified.
The attributes times, atLeast, atMost, are mutually exclusive. Only one should be used.
The messageProcessor attribute accepts regular expressions. You could create the same verification as follows:
Verify using regular expressions
<mock:verify-call messageProcessor=".*:set-payload" times="1"/>
In the example above, we define a verification for a message processor named set-payload, disregarding which namespace the message processor belongs to.
The regular expression language is the same as Java.

Defining Verifications with Message Processor Attributes

The definition of a verification is based on matchers, that is, parameters that match features of the desired message processor. Defining a verification solely on the name of the message processor largely limits your scope and actions. For this reason, MUnit allows you to verify by defining matchers over the value of a message processor’s attributes.

          
       
1
2
3
4
5
<mock:verify-call messageProcessor="mule:set-payload">
  <mock:with-attributes>
    <mock:with-attribute whereValue="#['Real Set Payload']" name="doc:name"/>
  </mock:with-attributes>
</mock:verify-call>
You can define as many attributes as you deem necessary to make the verification as representative as possible. When defining an attribute, you do so by defining:
Attribute Name Description
name
The name of the attribute. This value is literal, it doesn’t support regular expressions.
whereValue
The value that the attribute of the real message processor should contain. It accepts MEL expressions. If left as a literal, it assumes a string value.
If the attribute you wish the Verify message processor to match is similar to config-ref and resolves to an actual bean, you can use the MUnit MEL function getBeanFromMuleContext('bean_name'). This function inspects the Mule registry and returns the bean with the matching name if present. See Assertion for details.

Defining Verifications with Java Code

The example below shows how to reproduce the same behavior described above, using the MUnit Java API.

         
      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import org.junit.Test;
import org.mule.munit.common.mocking.Attribute;
import org.mule.munit.runner.functional.FunctionalMunitSuite;

public class TheTest extends FunctionalMunitSuite {

  @Test
  public void test() {
    Attribute attribute = Attribute.attribute("name").
      ofNamespace("doc").withValue("Real Set Payload"); 

    verifyCallOfMessageProcessor("set-payload") 
    .ofNamespace("mule")                        
    .withAttributes(attribute)                  
    .times(1);                                  

  }
}

Define the real message processor attribute to match.

Define the message processor’s name to verify (accepts regular expressions).

Define the message processor’s namespace to verify (accepts regular expressions).

Set the message processor’s attribute defined in Note #1.

Define the amount of times (could also be atLeast(1) or atMost(1)).
INFO: Java does not provide default values for parameters times, atLeast or atMost, so you need to provide the value of the parameter that you use.

Mock Message Processor

Mock Message Processor

Overview

The Mock feature provided by MUnit allows you to define mocked behavior for a message processor. In this case, MUnit replaces the normal behavior of the message processor with the behavior you define. Thus you can modify how a specific message processor responds when it is called with a particular set of attributes.

Defining Mocks

Defining a mock entails several tasks, listed in the sections below.
Using the parameters entailed in the above tasks, you can tell MUnit how to replace the normal behavior of the message processor with the one you define.
It is not possible to mock flow control message processors, such as Filter or Choice.
For the purpose of this documentation, we assume we are testing the following Mule code:
Test code

         
      
1
2
3
<flow name="exampleFlow">
  <set-payload value="#['real_payload']" doc:name="Real Set Payload"/>
</flow>

Defining the Message Processor to Mock

When defining a mock, we make use of the when message processor, as shown below.

          
       
1
2
3
<mock:when messageProcessor="mule:set-payload">

</mock:when>
Attribute Name Description
messageProcessor
Specifies which message processor to mock. The definition takes the form {name-space}:{message-processor-name}. Regular expressions are allowed.
The messageProcessor attribute accepts regular expressions. For example, you can create a mock as follows:

          
       
1
2
3
<mock:when messageProcessor=".*:set-payload">

</mock:when>
The example above defines a mock for a message processor named set-payload, disregarding which namespace the message processor belongs to.
The regular expression language is the same as Java.

Defining Mocked Behavior Using Message Processor Attributes

A mock definition is based on matchers, that is, parameters that match features of the desired message processor. Defining a mock solely on the name of the message processor largely limits your scope and actions regarding the mock. For this reason, MUnit allows you to define a mock by defining matchers over the value of a message processor’s attributes.
Defining a mock by attributes

          
       
1
2
3
4
5
<mock:when messageProcessor="mule:set-payload">
  <mock:with-attributes>
    <mock:with-attribute whereValue="#['Real Set Payload']" name="doc:name"/>
  </mock:with-attributes>
</mock:when>
You can define as many attributes as you deem necessary to make the mock as representative as possible. When defining an attribute, you do so by defining:
Attribute Name Description
name
The name of the attribute. This value is literal, it doesn’t support regular expressions
whereValue
The value that the attribute of the real message processor should contain. It accepts MEL expressions. If left as a literal, it assumes a string value.
MUnit allows you to define mocks based on the content of the Mule message.
If the attribute you wish to use when mocking is similar to config-ref and resolves to an actual bean, you can use the MUnit MEL function getBeanFromMuleContext('bean_name'). This function inspects the Mule registry and returns the bean with the matching name if present. See Assertion Message Processor for details.
Several attributes in Mule’s message processors support expressions, which are evaluated at runtime. MUnit is smart enough to understand this.
Suppose we change the test code to:

          
       
1
2
3
4
5
6
<flow name="exampleFlow">
  <set-variable variableName="#[1==1? 'var_true': 'var_false']"
    value="#['some value']" doc:name="Variable"/>
  <set-variable variableName="#[1==2? 'var_true': 'var_false']"
    value="#['some value']" doc:name="Variable"/>
</flow>
In this example, we are going to mock only the first set-variable. To specify this, we use attributes, as shown below:

          
       
1
2
3
4
5
<mock:when messageProcessor="mule:set-variable">
  <mock:with-attributes>
    <mock:with-attribute whereValue="#['var_true']" name="variableName"/>
  </mock:with-attributes>
</mock:when>

A Word About Mocking Flow-ref

In MUnit, you don’t mock or verify a flow-ref message processor, but the flow or sub-flow that would be invoked by flow-ref.

          
       
1
2
<mock:when messageProcessor="mule:sub-flow">
</mock:when>
Notice that neither flow or sub-flow have the attribute doc:name; the attribute name is used instead. So, to mock a flow-ref to a flow:

          
       
1
2
3
4
5
<mock:when messageProcessor="mule:flow">
  <mock:with-attributes>
    <mock:with-attribute whereValue="FlowName" name="name"/>
  </mock:with-attributes>
</mock:when>
Also, note that to mock a sub-flow you can’t just type the name of the sub-flow. Instead, you need to use the MUnit matcher matchContains:

          
       
1
2
3
4
5
<mock:when messageProcessor="mule:sub-flow">
  <mock:with-attributes>
    <mock:with-attribute whereValue="#[matchContains('Sub_Flow_name')]" name="name"/>
  </mock:with-attributes>
</mock:when>
#[matchContains('exampleSub_Flow1')]
Using matchContains is not necessary when verifying or mocking flows, only sub-flows.
When mocking or verifying a sub-flow and using the name attribute, always use the MUnit matcher matchContains.

Defining the Payload of the Mock Response

When mocking a message processor, you can define the Mule message that the mocked message processor should return.

          
       
1
2
3
4
5
6
<mock:when messageProcessor="mule:set-payload">
  <mock:with-attributes>
    <mock:with-attribute whereValue="#['Real Set Payload']" name="doc:name"/>
  </mock:with-attributes>
  <mock:then-return payload="#['mocked_payload']"/> 
</mock:when>

Define the message response.
Attribute Name Description
payload
Defines the contents of the mocked payload.
encoding
Defines the encoding of the message. This attribute is optional.
mimeType
Defines the MIME type of the message. This attribute is optional.

Returning the Original Payload

If you don’t want to mock the payload of the message processor and want to return the original payload, you can use the function samePayload().

           
        
1
2
3
4
5
6
<mock:when messageProcessor="mule:set-payload">
  <mock:with-attributes>
    <mock:with-attribute whereValue="#['Real Set Payload']" name="doc:name"/>
  </mock:with-attributes>
  <mock:then-return payload="#[samePayload()]"/> 
</mock:when>

Return the same payload
Omitting the mock:then-return property also returns the original payload but if you want to return the original payload and mock message properties you can use the samePayload function to achieve this.

           
        
1
2
3
4
5
6
7
8
9
10
<mock:when messageProcessor="mule:set-payload">
  <mock:with-attributes>
    <mock:with-attribute whereValue="#['Real Set Payload']" name="doc:name"/>
  </mock:with-attributes>
  <mock:then-return payload="#[samePayload()]"> 
    <mock:inbound-properties>
      <mock:inbound-property key="property" value="#['propertyValue']"/> 
    </mock:inbound-properties>
  </mock:then-return>
</mock:when>

Return the same payload

Mock message property

Loading Payloads From Files and Scripts

Sometimes it’s easier to load complex payloads from a file. MUnit offers a set of MEL functions to help you achieve this.
Function Name Attribute Description
getResource()
Name of a classpath resource.
Loads a resource from the project’s classpath and returns an MuniResource object. This object supports util methods such as: asStream() , asString() and asByteArray()
resultOfScript()
Name of a declared script bean.
Executes a script that is registered in the application, either in the MUnit suite or in one of the imported files.
Example: getResource

           
        
1
2
3
<mock:then-return payload="#[getResource('users.xml').asStream()]"/>    
<mock:then-return payload="#[getResource('users.xml').asString()]"/>    
<mock:then-return payload="#[getResource('users.xml').asByteArray()]"/> 

Return the content of users.xml as an input stream.

Return the content of users.xml as a string.

Return the content of users.xml as a byte array.
Example: resultOfScript

           
        
1
2
3
4
5
6
7
8
9
10
11
12
<script:script name="groovyScriptPayloadGenerator" engine="groovy"><![CDATA[  
  List<String> lists = new ArrayList<String>();
  lists.add("item1");
  lists.add("item2");
  lists.add("item3");

  return lists;]]>
</script:script> ... <mock:then-return payload="#[resultOfScript('groovyScriptPayloadGenerator')]"/> 
  ...

Script definition.

Return mock payload as the result of the groovyScriptPayloadGenerator script.

Defining the Properties of a Mock Response

With MUnit you can also define the properties of the message to be returned by a mock. The following code expands on the example above to modify the returned payload:

          
       
1
2
3
4
5
6
7
8
9
10
<mock:when messageProcessor="mule:set-payload">
  <mock:with-attributes>
    <mock:with-attribute whereValue="#['Real Set Payload']" name="doc:name"/>
  </mock:with-attributes>
  <mock:then-return payload="#['mocked_payload']">
    <mock:invocation-properties>
      <mock:invocation-property key="property_name" value="#['property_value']"/>
    </mock:invocation-properties>
  </mock:then-return>
</mock:when>
Attribute Name
Description
key
The name of the property. This value is always literal.
value
Defines the value the property should contain. It accepts MEL expressions. If left as a literal, it assumes a string value.
encoding
Defines the encoding of the message. This attribute is optional.
mimeType
Defines the MIME type of the message. This attribute is optional.
You can define any of the following property types:
  • Inbound Properties
  • Invocation Properties
  • Outbound Properties
You can use the same MEL functions, getResource(), resultOfScript() and getBeanFromMuleContext() to define the content of a Mule message property.

Defining Mock Response Exceptions

In some scenarios, you may want to validate how your flow behaves if a message processor throws an exception. For these cases MUnit offers the throw-an exception feature.
This feature is offered through a different message processor: mock:throw-an.

          
       
1
2
3
4
<mock:config name="mock_config" doc:name="Mock configuration"/>
...
<mock:throw-an whenCalling="mule:set-payload" exception-ref="#[new java.lang.Exception()]">
</mock:throw-an>
In the structure of the throw-an message processor, you define which message processor you wish to mock, just like the when message processor. However, here you also need to define the exception that should be thrown by the mocked message processor.
Message Processor Attributes
Name Description
whenCalling
Describes which message processor we want to mock, in the form {name-space}:{message-processor-name}. Supports regular expressions.
exception-ref
Defines the exception the mocked payload should throw.

Defining a Mock Response Exception With Message Processor Attributes

You can use matchers — parameters that match features of the desired message processor — to create a mock to throw an exception.

           
        
1
2
3
4
5
<mock:throw-an whenCalling="mule:set-payload" exception-ref="#[new java.lang.Exception()]">
  <mock:with-attributes>
    <mock:with-attribute whereValue="#['Real Set Payload']" name="doc:name"/>
  </mock:with-attributes>
</mock:throw-an>
You can define as many attributes as you deem necessary to make the mock as representative as possible. When defining an attribute, you do so by defining:
Attribute Name Description
name
The name of the attribute. This value is literal, it doesn’t support regular expressions.
whereValue
Defines the value that the attribute of the real message processor should contain.

Defining Mocks with Java Code

The code below reproduces the example described above, but with the MUnit Java API.

         
      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import org.junit.Test;
import org.mule.api.MuleMessage;
import org.mule.munit.common.mocking.Attribute;
import org.mule.munit.runner.functional.FunctionalMunitSuite;

public class TheTest extends FunctionalMunitSuite {

  @Test
  public void test() {
    Attribute attribute =
      Attribute.attribute("name").ofNamespace("doc").
        withValue("Real Set Payload"); 

    MuleMessage messageToBeReturned =
      muleMessageWithPayload("Real Set Payload"); 
    messageToBeReturned.setProperty("property_name",
      "property_value",PropertyScope.INBOUND); 

    whenMessageProcessor("set-payload") 
    .ofNamespace("mule")                
    .withAttributes(attribute)          
    .thenReturn(messageToBeReturned);   
  }

}

Define the real message processor attribute to match.

Define the Mule message that should be returned by the mocked message processor.

Define the properties of the Mule message that should be returned by the mocked message processor.

Define the name of the message processor to be mocked (accepts regular expressions).

Define the name of the namespace of the message processor to be mocked (accepts regular expressions).

Set the message processor’s attribute defined in (1).

Set the message to be returned by the mocked message processor defined in (3).

Thứ Ba, 19 tháng 4, 2016

MUnit Suite

MUnit Suite

This page and related MUnit pages are focused on XML; however, MUnit is fully compatible with Anypoint Studio’s graphical user interface. Within the Studio environment, you can create, design and run MUnit tests just like you would Mule applications. You can even use Studio’s Visual Debugger to debug your MUnit tests. For an overview of MUnit in Studio, see Using MUnit in Anypoint Studio.

Definition

The base of the MUnit Framework consists of MUnit Test Suite files. These files are the .xml files located under the src/test/munit folder in your Mule application’s folder structure. Each MUnit Test Suite file is a collection of MUnit tests. It is meant to work on its own, and should be able to run independently from any other MUnit test suite files.

Components of an MUnit Test Suite

An MUnit test suite file should contain any combination of the following components:
  • Imports
  • Bean Definitions
  • Before/After Suites
  • Before/After Tests
  • MUnit Tests
Each MUnit test suite file is, behind the scenes, no different than a Mule application XML file. You can use several of the Mule top level elements such as flow, sub-flow, scripts, etc.

Defining Imports

Each MUnit suite is meant to test a particular set of Mule flows. To do that, you need to tell MUnit where those flows are defined in your application structure. For this we use imports, which are in fact spring imports.
Note: MUnit does not support Mule Domains.
Spring Import Example
1
2
3
<spring:beans>
  <spring:import resource="classpath:your-production-code.xml"/>
</spring:beans>
If your application is spread across multiple files and the components in those files cross-reference each other, you need to import all of the files.
Currently, MUnit Suite doesn’t support the use of components defined in Shared Resources. It’s required to define those components explicitly in the test suit file in order to execute the test.
Ideally, your production code and your flows should be arranged in a cohesive way — this improves readability, maintainability and testability.

Defining Before and After Suites

As with other testing frameworks, MUnit provides certain features around the test suite concept. In particular, you can add processing/actions to be run before and/orafter the entire MUnit Test Suite executions.

Defining a Before Suite

The MUnit Before Suite is a scope. It can contain code that is meant to be executedbefore the whole suite.
For instance, let’s suppose you have an MUnit Test Suite file with four tests. The code inside an MUnit Before Suite runs just once, before your four tests.
The MUnit Before Suite is a top level scope, so you can have as many Before Suites as you need. They all follow the same execution rule: Run before the tests, just once.
If there is more than one Before Suite, MUnit does not guarantee the order in which the Before Suites run amongst themselves.
Before Suite example
1
2
3
<munit:before-suite name="before.suite" description="A description">
  <!-- some mule code here --> 
</munit:before-suite >
Define the code you want to run
Attribute NameDescription
name
Defines the name of the Before suite. The name must be unique inside the suite.
description
Describes the actions performed.
One instance in which the MUnit Before Suite is useful is when you need to set up a test environment before the whole test runs.

Defining an After Suite

The MUnit After Suite is a scope. It can contain code that is meant to be executedafter the whole suite.
For instance, let’s suppose you have an MUnit Test Suite File with four tests. The code inside an MUnit After Suite, runs just once, after all your tests.
The MUnit After Suite is a top level scope, thus you can have as many After Suites as you need. They all follow the same execution rule: Run after the tests, just once.
If there is more than one After Suite, MUnit does not guarantee the order in which the After Suites run amongst themselves.
After Suite example
1
2
3
<munit:after-suite  name="after.suite" description="A description">
  <!-- some Mule code here --> 
</munit:after-suite >
Define the code you want to run
Attribute NameDescription
name
Defines the name of the After suite. The name must be unique inside the suite.
description
Describes the actions performed.
One instance in which the MUnit After Suite is useful is when you need to set up a test environment after the whole test runs.

Defining Before and After Tests

MUnit provides the ability to perform Before and After tests. These are similar to the concepts defined by JUnit. You can add processing/actions to be run beforeand/or after the execution of each MUnit Test suite.

Defining a Before Test

The MUnit Before Test is a scope. It can contain code that is meant to be executedbefore each test.
For instance, let’s suppose you have an MUnit Test Suite file with four tests. The code inside an MUnit Before test runs before each of your four tests; it runs four times.
The MUnit Before Test is a top-level scope, thus you can have as many Before tests as you need. They all follow the same execution rule: Run before each test.
If there is more than one Before test, MUnit does not guarantee the order in which the Before tests run amongst themselves.
Before Test example
1
2
3
<munit:before-test name="before.tests" description="A description">
  <!-- some mule code here --> 
</munit:before-test>
Define the code you want to run
Attribute NameDescription
name
Defines the name of the Before test. The name must be unique inside the test.
description
Describes the actions performed.
One instance in which the MUnit After Suite is useful is when you need to set up a test environment after the whole test runs.

Defining an After Test

The MUnit After Test is a scope. It can contain code that is meant to be executedafter each test.
For instance, let’s suppose you have an MUnit Test Suite file with four tests. The code inside an MUnit After Test runs after each of your four tests; it runs four times.
The MUnit After Test is a top level scope, so you can have as many After Tests as you need. They all follow the same execution rule: Run after each test.
If there is more than one After test, MUnit does not guarantee the order in which the After Tests run amongst themselves.
After Test example
1
2
3
<munit:after-test  name="after.test" description="A description">
  <!-- some mule code here --> 
</munit:after-test>
Define the code you want to run
Attribute NameDescription
name
Defines the name of the After test. The name must be unique inside the test.
description
Describes the actions performed.
One instance in which the MUnit After test is useful is when you need to set up a test environment after the whole test runs.

Defining an MUnit Test

The MUnit Test is the basic building block of an MUnit Test Suite. It represents each test scenario you want to try.
MUnit Test example
1
2
<munit:test name="my-flow-Test" description="Test to verify scenario 1">
</munit:test>
Table 1. MUnit Test Attributes
NameDescription
name
Mandatory. Defines the name of the test. The name must be unique inside the test suite.
description
Mandatory. Describes the scenario being tested.
ignore
Defines if the test should be ignored. If not present, the test is not ignored.
expectException
Defines the exception that should be received after the execution of this test.

Defining Properties

In MUnit, you can load properties from the mule­-app.properties file as well as using the context:property-placeholder to load properties from an additional file.
MUnit provides several ways to override these properties when running MUnit with Anypoint Studio. Properties for the mule-app.properties file are loaded as System properties.

Defining an MUnit Test Description

In MUnit, it’s mandatory that you write a description in your test, that is, thedescription attribute is mandatory.
Ideally, you should write a useful, representative description of the scenario you are testing. This description displays in the test console before running the test, and also in the reports.
The more representative the description, the more easy to read and troubleshoot any failures.
1
2
<munit:test name="testingEchoFlow"
    description="We want to test that the flow always returns the same payload as we had before calling it.">

Defining an MUnit Test To Ignore

There may be scenarios where you need to shoot-down a test. Whether this be because the test is failing or because it has nasty side effect. The point is you shouldn’t have to comment out the code.
In some scenarios, you may find it necessary to bypass a defined test, for example if the test fails or produces unwanted side-effects. In this case, MUnit allows you to ignore a specific test so you don’t have to comment out the code.
You can ignore any of your tests by adding the ignore boolean to the test definition, as shown below.
MUnit ignore test example
1
2
3
4
<munit:test name="my-flow-Test"
      ignore="true"               
      description="Test to verify scenario 1">
</munit:test>
Ignore test my-flow-Test
Valid values for ignore are true and false. If the attribute is not present, the default is false.

Defining an Expected Exception

Sometimes, the only thing you want to validate is that the flow or sub-flow you are testing fails and throws a specific exception, which depends on the business logic being tested. In these cases, MUnit provides a simple way to validate the scenario.
You can validate a specific scenario by adding the attribute expectException, as shown below.
MUnit test expect exception example
1
2
3
<munit:test name="testExceptions" description="Test Exceptions" expectException="">
  <flow-ref name="exceptionFlow"/>
</munit:test>
The attribute expectException expects one of the following:
  • A literal exception class name (canonical form)
  • A MEL expression
MUnit test expected exception class name example
1
2
3
<munit:test name="testExceptions" description="Test Exceptions" expectException="java.lang.RuntimException">
  <flow-ref name="exceptionFlow"/>
</munit:test>
If you define that your test expects an exception and none is thrown, the test fails immediately.

expectException - Literal Value

When you provide a literal value, it should take the form of the canonical class nameof the exception that is expected. In these cases, Mule always throws aMuleMessagingException. MUnit validates the provided classname if the underlying cause of the MuleMessagingException thrown is of the exact same type.
When providing exceptions in this way, a subclass of the provided exception does not pass the validation — MUnit looks for the exact same type.

expectException - MEL Expression Value

If you choose to use expressions, Mule itself offers a collection of MEL expressions that simplifies the validations of the exceptions thrown.
NameDescription
exception.causedBy(exception_type)
Evaluates if the exception was caused by an (instance of) the provided exception type. Example:exception.causedBy(org.mule.example.ExceptionType)
exception.causedExactlyBy(exception_type)
Evaluates if the exception was caused by the specific exception type provided, discarding all other exception types. For example, if the provided exception type isNullPointerException, the expression returns true only if the test returns a NullPointerException. Example:exception.causedExactlyBy(org.mule.example.ExceptionType)
exception.causeMatches(<regex>)
Checks the cause exception type name matches the provided regex. Supports any java regex plus, prefix, suffix. Example:exception.causeMatches(org.mule.example.*)
You can combine any expressions as a boolean expression. For example:
exception.causeMatches('*') && !exception.causedBy(java.lang.ArithmeticException) && !exception.causedBy(org.mule.api.registry.ResolverException)
This MEL expression is meant to be used with the expressions listed above, but no verification is performed done to avoid other usages. The only contract being enforced is: The MEL expression should return a boolean value. If true, the test is successful.
If the MEL expression returns something that cannot be cast to a Boolean value, the test fails.
All MEL expression shortcuts, such as message or payload, are valid. Just bear in mind that if an exception is thrown, the original payload most likely is lost.