Skip to content

elifserver/interfaceStubVersusWiremock

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 

Repository files navigation

WireMock vs Interface-Based Stubs

Talk: "WireMock vs Interface-Based Stubs: Rethinking Integration Testing" A practical Spring Boot demo


The Problem

Integration tests often depend on external services. Most teams reach for WireMock by default — but is it always the right choice?

This demo shows the same 5 business scenarios tested with two different approaches, so you can compare them side-by-side.


System Under Test

OrderService
     ↓
CustomerGateway (interface)
     ↓
CustomerService (external HTTP dependency)

Business rules in OrderService:

  1. Customer must exist
  2. Customer must be active
  3. Order amount must not exceed customer's credit limit

Two Testing Approaches

Approach 1 — WireMock (src/test/java/com/demo/wiremock/)

  • Full Spring context loaded
  • HttpCustomerGateway makes real HTTP calls
  • WireMock intercepts at the network level
  • HTTP serialization, status codes, headers all exercised
wireMockServer.stubFor(get(urlEqualTo("/customers/CUST-001"))
    .willReturn(aResponse()
        .withStatus(200)
        .withHeader("Content-Type", "application/json")
        .withBody("""
            { "id": "CUST-001", "active": true, "creditLimit": 1000.0 }
        """)));

Approach 2 — Interface Stub (src/test/java/com/demo/stub/)

  • No Spring context — plain Java objects
  • StubCustomerGateway injected directly
  • No HTTP, no JSON, no network
var gateway = new StubCustomerGateway()
        .withActiveCustomer("CUST-001", 1000.0);

var orderService = new OrderService(gateway);

The 5 Test Scenarios

# Scenario Expected Result
1 Active customer, sufficient credit CREATED
2 Inactive customer REJECTED
3 Customer not found (404) REJECTED
4 Customer service unavailable (500) FAILED
5 Amount exceeds credit limit REJECTED

Both test classes cover all 5 scenarios.


Comparison Table

Criterion WireMock Interface Stub
Tests HTTP behaviour
Catches serialization bugs
Validates HTTP contract
Speed ⚠️ Slower ✅ Fast
Setup complexity ⚠️ High ✅ Low
Readability ⚠️ Medium ✅ High
Compile-time safety
Refactor-friendly
Risk of contract drift ⚠️ ⚠️

Key Design Decision

The CustomerGateway interface is the crucial boundary that enables both approaches:

public interface CustomerGateway {
    Customer getCustomer(String customerId);
}
  • ProductionHttpCustomerGateway (real HTTP)
  • WireMock testsHttpCustomerGateway + WireMock server
  • Stub testsStubCustomerGateway (fake implementation)

The lesson: Good production design (dependency inversion) naturally enables both testing strategies. You don't need to bend your code for tests — you need well-defined boundaries.


The Talk's Core Message

WireMock is invaluable for testing HTTP contracts and integration behaviour. Interface-based stubs are better for fast feedback and business logic. Use both — but for different purposes.

Or put another way:

"When do mocks become lies?" When your stub drifts from the real service behaviour — and you don't know it.


Running the Demo

# Run all tests
mvn test

# Run only WireMock tests
mvn test -Dtest="*WireMock*"

# Run only Stub tests
mvn test -Dtest="*Stub*"

Project Structure

src/
├── main/java/com/demo/
│   ├── gateway/
│   │   ├── CustomerGateway.java        ← The key interface
│   │   └── HttpCustomerGateway.java    ← Production HTTP implementation
│   ├── service/
│   │   └── OrderService.java           ← Business logic (system under test)
│   ├── model/
│   │   ├── Customer.java
│   │   ├── Order.java
│   │   └── OrderRequest.java
│   └── exception/
│       ├── CustomerNotFoundException.java
│       └── CustomerServiceException.java
│
└── test/java/com/demo/
    ├── wiremock/
    │   └── OrderServiceWireMockTest.java   ← Approach 1
    └── stub/
        ├── StubCustomerGateway.java         ← Fake implementation
        └── OrderServiceStubTest.java        ← Approach 2

Tech Stack

  • Java 17
  • Spring Boot 3.2
  • WireMock 3.3
  • JUnit 5
  • AssertJ
  • Lombok
  • Maven

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages