Back to course overview
6
Module 6 of 7

Testing, CI/CD & Best Practices

Write MUnit tests for your Mule flows, set up a Maven build, and automate deployment through a GitHub Actions CI/CD pipeline.

2 lessons~3 hours
1

Unit Testing with MUnit

MUnit is MuleSoft's native testing framework — tests are XML-based flows that mock connectors and assert on payloads.

An MUnit test suite is an XML file in `src/test/munit/`. Each test case is an `<munit:test>` element containing behaviour mocks, the flow to execute, and assertions.

Mock the behaviour of connectors using `<munit-tools:mock-when>` to return controlled responses, keeping tests fast and deterministic without needing real database or HTTP connections.

The `<munit-tools:assert-that>` element supports a rich set of matchers: `equalTo`, `containsString`, `hasSize`, `isNull`, etc. Always assert both the payload shape and the HTTP status variable.

MUnit test for get-orders-flowxml
<munit:test name="get-orders-flow-success-test"
            description="Should return orders when DB returns results">

  <munit:behavior>
    <munit-tools:mock-when processor="db:select">
      <munit-tools:with-attributes>
        <munit-tools:with-attribute attributeName="doc:name" whereValue="Query Orders" />
      </munit-tools:with-attributes>
      <munit-tools:then-return>
        <munit-tools:payload value="#[[{ORDER_ID: '1', CUSTOMER_NAME: 'Alice', TOTAL_AMOUNT: 99.99}]]" />
      </munit-tools:then-return>
    </munit-tools:mock-when>
  </munit:behavior>

  <munit:execution>
    <flow-ref name="get-orders-flow" />
  </munit:execution>

  <munit:validation>
    <munit-tools:assert-that expression="#[sizeOf(payload)]"
                             is="#[MunitTools::equalTo(1)]" />
    <munit-tools:assert-that expression="#[payload[0].customer]"
                             is="#[MunitTools::equalTo('Alice')]" />
    <munit-tools:assert-that expression="#[vars.httpStatus]"
                             is="#[MunitTools::equalTo('200')]" />
  </munit:validation>
</munit:test>
2

GitHub Actions CI/CD Pipeline

Automate build, test, and deployment of your Mule application on every push to main.

The standard Mule CI/CD pipeline has three stages: build (compile and run MUnit tests with Maven), package (create the deployable JAR), and deploy (push to CloudHub via the Mule Maven Plugin).

Store secrets (Anypoint credentials, connected app client ID/secret) in GitHub Actions Secrets — never hardcode them in the workflow YAML or the `pom.xml`.

Use environment-specific workflows: `push` to `develop` deploys to Dev, a PR merge to `main` deploys to Production after a mandatory review gate.

.github/workflows/deploy.ymlyaml
name: Mule CI/CD

on:
  push:
    branches: [main]

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up JDK 17
        uses: actions/setup-java@v4
        with:
          java-version: '17'
          distribution: 'temurin'

      - name: Add MuleSoft Exchange credentials
        run: |
          mkdir -p ~/.m2
          cat > ~/.m2/settings.xml << 'EOF'
          <settings>
            <servers>
              <server>
                <id>anypoint-exchange-v3</id>
                <username>~~~Client~~~</username>
                <password>${{ secrets.CONNECTED_APP_SECRET }}</password>
              </server>
            </servers>
          </settings>
          EOF

      - name: Build and test
        run: mvn clean verify -DskipDeployment

      - name: Deploy to CloudHub 2.0
        run: |
          mvn deploy -DmuleDeploy \
            -Dcloudhub2.environment=Production \
            -Dcloudhub2.applicationName=orders-api \
            -Dcloudhub2.connectedApp.clientId=${{ secrets.CONNECTED_APP_CLIENT_ID }} \
            -Dcloudhub2.connectedApp.clientSecret=${{ secrets.CONNECTED_APP_SECRET }}