Skip to main content
Global
AIMenta
Blog

APAC Contract Testing and Service Virtualization Guide 2026: Pact, WireMock, and Mockoon for Microservices Quality Engineering

A practitioner guide for APAC microservices engineering teams implementing contract testing and service virtualization in 2026 — covering Pact for consumer-driven contract testing between APAC services with Pact Broker and can-i-deploy gates, WireMock for HTTP service virtualization of APAC payment gateways and banking APIs in CI/CD Docker environments, and Mockoon for APAC frontend developer API mocking against OpenAPI specifications.

AE By AIMenta Editorial Team ·

The APAC Integration Testing Dependency Problem

APAC engineering teams with microservices architectures face an integration testing paradox: comprehensive integration testing requires all dependent services to be running, but running all APAC services simultaneously in a test environment is expensive, slow, and fragile.

The result is one of two failure modes:

Too little integration testing: APAC unit tests pass, but integration bugs between services are discovered in APAC staging or production — where the cost of discovery (rollback, hotfix, APAC incident response) is high.

Too much integration environment dependency: APAC CI/CD pipelines require an APAC integration environment with all services deployed, creating bottlenecks when APAC services are unavailable, unstable, or still being developed.

Three tools address different aspects of this APAC integration testing problem without requiring live APAC dependent services:

Pact — contract testing: verify that APAC consumers and providers agree on API interactions without deploying either.

WireMock — service virtualization: stub APAC third-party APIs that APAC services cannot control (payment gateways, banking APIs, government portals).

Mockoon — developer mocking: create APAC mock APIs for APAC frontend and mobile development before APAC backend implementation is ready.


Pact: Consumer-Driven Contract Testing for APAC Microservices

The Pact workflow for APAC teams

APAC Pact Workflow:

1. APAC Consumer writes Pact test
   └─ Consumer test defines expected APAC API interactions
   └─ Pact records interactions to pact.json file

2. APAC Consumer publishes pact to Pact Broker
   └─ pact broker publish ./pacts --broker-base-url http://apac-pactbroker.internal

3. APAC Provider verifies pact
   └─ Provider CI fetches pact from APAC broker
   └─ Pact runs mock consumer against real APAC provider
   └─ Verification result published to APAC broker

4. APAC can-i-deploy gate
   └─ Before APAC deployment: pact-broker can-i-deploy --pacticipant apac-payments-service
   └─ Gate passes only if all APAC consumer contracts verified for this version

Pact consumer test in TypeScript for APAC

// apac-payment-consumer.pact.spec.ts
import { PactV3, MatchersV3 } from '@pact-foundation/pact';
import path from 'path';

const { like, eachLike, string, number } = MatchersV3;

const provider = new PactV3({
  consumer: 'apac-checkout-service',
  provider: 'apac-payments-service',
  dir: path.resolve(process.cwd(), 'pacts'),
  logLevel: 'warn',
});

describe('APAC Payments Service contract', () => {
  test('creates a payment for a Singapore customer', async () => {
    // Define APAC interaction: consumer expects this from provider
    await provider
      .given('APAC customer CUST-SG-123 exists with verified KYC')
      .uponReceiving('a request to create a Singapore payment')
      .withRequest({
        method: 'POST',
        path: '/v2/payments',
        headers: {
          'Content-Type': 'application/json',
          'X-APAC-Region': 'SEA',
        },
        body: {
          customer_id: 'CUST-SG-123',
          amount: like(15000),           // Flexible: any integer
          currency: 'SGD',
          payment_method: 'card',
        },
      })
      .willRespondWith({
        status: 201,
        headers: { 'Content-Type': 'application/json' },
        body: {
          payment_id: string('PAY-APAC-123'),   // Flexible: any string
          status: 'pending',
          amount: like(15000),
          currency: 'SGD',
          created_at: string('2026-04-28T10:00:00Z'),
        },
      })
      .executeTest(async (mockServer) => {
        // Consumer calls the mock APAC provider
        const response = await createAPACPayment(mockServer.url, {
          customer_id: 'CUST-SG-123',
          amount: 15000,
          currency: 'SGD',
          payment_method: 'card',
        });

        expect(response.status).toBe(201);
        expect(response.data.payment_id).toBeDefined();
        expect(response.data.status).toBe('pending');
      });
  });
});

Pact provider verification in Java for APAC

// APACPaymentsServicePactVerificationTest.java
@Provider("apac-payments-service")
@PactBroker(
    url = "http://apac-pactbroker.platform.svc.cluster.local",
    authentication = @PactBrokerAuth(token = "${APAC_PACT_BROKER_TOKEN}"),
    enablePendingPacts = "true"
)
@ExtendWith(PactVerificationInvocationContextProvider.class)
class APACPaymentsServicePactVerificationTest {

    @BeforeEach
    void before(PactVerificationContext context) {
        context.setTarget(new HttpTestTarget("localhost", 8080));
    }

    @TestTemplate
    @ExtendWith(PactVerificationInvocationContextProvider.class)
    void verifyAPACPact(PactVerificationContext context) {
        context.verifyInteraction();
    }

    // Provider state setup: create APAC test data for each Pact state
    @State("APAC customer CUST-SG-123 exists with verified KYC")
    void setupSingaporeCustomer() {
        customerRepository.save(APACCustomer.builder()
            .id("CUST-SG-123")
            .country("SG")
            .kycStatus(KycStatus.VERIFIED)
            .build());
    }
}

Pact Broker self-hosted deployment

# docker-compose.yml: APAC Pact Broker with PostgreSQL
version: '3.8'

services:
  apac-pact-broker:
    image: pactfoundation/pact-broker:latest
    ports:
      - "9292:9292"
    environment:
      PACT_BROKER_DATABASE_URL: "postgres://pact:${APAC_POSTGRES_PASSWORD}@apac-pact-postgres:5432/pact_broker"
      PACT_BROKER_ALLOW_PUBLIC_READ: "true"
      PACT_BROKER_BASIC_AUTH_USERNAME: "apac-pact-admin"
      PACT_BROKER_BASIC_AUTH_PASSWORD: "${APAC_PACT_ADMIN_PASSWORD}"
    depends_on:
      - apac-pact-postgres

  apac-pact-postgres:
    image: postgres:16
    environment:
      POSTGRES_DB: pact_broker
      POSTGRES_USER: pact
      POSTGRES_PASSWORD: "${APAC_POSTGRES_PASSWORD}"

WireMock: Service Virtualization for APAC Third-Party APIs

WireMock in APAC CI/CD Docker Compose

# docker-compose.test.yml: APAC integration test environment
version: '3.8'

services:
  apac-payments-service:
    image: apac-org/payments-service:${IMAGE_TAG}
    environment:
      # Point to WireMock stubs instead of live APAC providers
      STRIPE_API_URL: http://apac-wiremock:8080/stripe
      PROMPTPAY_API_URL: http://apac-wiremock:8080/promptpay
      PAYNOW_API_URL: http://apac-wiremock:8080/paynow
      DB_URL: postgresql://apac-test-db:5432/test_db

  apac-wiremock:
    image: wiremock/wiremock:latest
    ports:
      - "8080:8080"
    volumes:
      - ./wiremock/mappings:/home/wiremock/mappings    # APAC stub definitions
      - ./wiremock/files:/home/wiremock/__files         # APAC response body files
    command: >
      --global-response-templating
      --verbose

  apac-test-db:
    image: postgres:16
    environment:
      POSTGRES_DB: test_db
      POSTGRES_PASSWORD: test

WireMock stub for APAC payment gateway scenarios

// wiremock/mappings/apac-stripe-success.json
{
  "request": {
    "method": "POST",
    "urlPattern": "/stripe/v1/payment_intents",
    "headers": {
      "X-APAC-Region": { "equalTo": "SEA" }
    }
  },
  "response": {
    "status": 200,
    "headers": { "Content-Type": "application/json" },
    "body": "{\"id\": \"pi_APAC_{{randomValue type='ALPHANUMERIC' length='24'}}\", \"status\": \"succeeded\", \"amount\": {{jsonPath request.body '$.amount'}}, \"currency\": \"sgd\"}"
  }
}
// wiremock/mappings/apac-stripe-card-declined.json
// Simulates APAC payment failure scenario — impossible to trigger reliably on live Stripe
{
  "request": {
    "method": "POST",
    "urlPattern": "/stripe/v1/payment_intents",
    "bodyPatterns": [
      { "matchesJsonPath": "$.payment_method[?(@.card.number == '4000000000000002')]" }
    ]
  },
  "response": {
    "status": 402,
    "headers": { "Content-Type": "application/json" },
    "jsonBody": {
      "error": {
        "type": "card_error",
        "code": "card_declined",
        "decline_code": "generic_decline",
        "message": "Your card was declined."
      }
    }
  }
}

Mockoon: Developer-First API Mocking for APAC Frontend Teams

Mockoon workflow for APAC parallel development

APAC Parallel Development with Mockoon:

Week 1: APAC Backend and Frontend teams align on OpenAPI spec
  → APAC Backend defines API contract in openapi.yaml
  → APAC Frontend imports openapi.yaml into Mockoon

Week 2-4: Parallel APAC development
  → APAC Backend builds real service implementation
  → APAC Frontend develops React/Vue/React Native against Mockoon
  → Both teams test against the same APAC API contract

Week 5: APAC Backend deploys to staging
  → APAC Frontend switches from Mockoon to staging endpoint
  → Contract alignment verified: Mockoon and real APAC API match spec
  → Integration issues surface before APAC production (not after)

Mockoon CLI for APAC CI/CD

# Install Mockoon CLI in APAC CI environment
npm install -g @mockoon/cli

# Start APAC mock server from Mockoon data file
mockoon-cli start \
  --data ./apac-mocks.json \
  --port 3001 \
  --log-transaction

# APAC GitHub Actions: run frontend tests against Mockoon
# .github/workflows/apac-frontend-test.yml
jobs:
  frontend-tests:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Start APAC API mocks
        run: |
          npm install -g @mockoon/cli
          mockoon-cli start --data ./apac-mocks.json --port 3001 &
          sleep 2  # Wait for APAC mock server to start

      - name: Run APAC frontend tests
        run: npm test
        env:
          NEXT_PUBLIC_API_URL: http://localhost:3001

Mockoon response templating for APAC dynamic responses

# Mockoon template: dynamic APAC customer response
{
  "customer_id": "CUST-{{faker 'random.alphaNumeric' 8 uppercase=true}}",
  "name": "{{faker 'name.fullName'}}",
  "country": "{{oneOf (array 'SG' 'MY' 'ID' 'PH' 'TH' 'VN')}}",
  "currency": "{{oneOf (array 'SGD' 'MYR' 'IDR' 'PHP' 'THB' 'VND')}}",
  "kyc_status": "{{oneOf (array 'verified' 'pending' 'failed')}}",
  "created_at": "{{now 'YYYY-MM-DDTHH:mm:ss'}}Z"
}

APAC Testing Tool Selection: Pact vs WireMock vs Mockoon

APAC Scenario                        → Tool        → Why

Test APAC service-to-service API     → Pact         Consumer-driven contract ensures
compatibility in CI without deploy    →              APAC API agreement without
                                      →              deployed APAC environments

Test against unavailable APAC        → WireMock     Stub external APAC APIs with
third-party API (payment, banking)    →              exact error scenarios; Docker-native

APAC frontend development against    → Mockoon      GUI-first creation; OpenAPI import;
incomplete backend service            →              unblocks APAC parallel development

APAC CI/CD integration tests         → WireMock     Rich APAC fault injection; Docker
with external service simulation      →              container; Java/REST API

APAC small team, non-JVM stack,      → Mockoon CLI  Lower APAC setup overhead vs
lightweight mock server               →              WireMock for simple APAC scenarios

Complete APAC quality engineering    → Pact +        Pact for APAC service contracts;
stack for microservices               WireMock       WireMock for APAC external stubs;
                                      + Mockoon      Mockoon for APAC frontend mocking

Related APAC Quality Engineering Resources

For the API testing tools that run against WireMock-stubbed APAC APIs, see the APAC API testing guide covering Hoppscotch, Bruno, and k6.

For the CI/CD pipelines that host APAC Pact verification and WireMock integration tests, see the APAC CI/CD platform engineering guide covering Tekton, Buildkite, and Gradle.

For the AI developer tools that APAC backend teams use to write Pact tests faster, see the APAC AI developer tools guide covering Aider, Continue, and Open WebUI.

Beyond this insight

Cross-reference our practice depth.

If this article matches your stage of thinking, the underlying capabilities ship across all six pillars, ten verticals, and nine Asian markets.

Keep reading

Related reading

Want this applied to your firm?

We use these frameworks daily in client engagements. Let's see what they look like for your stage and market.