0
# JUnit Integration
1
2
Seamless integration with JUnit 4 and JUnit 5 testing frameworks providing lifecycle management, parameter injection, and declarative configuration for comprehensive test automation with WireMock.
3
4
## Capabilities
5
6
### JUnit 4 Integration
7
8
Complete JUnit 4 support with test rules for method-level and class-level server lifecycle management.
9
10
```java { .api }
11
/**
12
* JUnit 4 test rule for method-level server lifecycle
13
*/
14
class WireMockRule extends WireMockServer implements TestRule {
15
// Constructors
16
/** Default constructor with dynamic port */
17
WireMockRule();
18
19
/** Constructor with specific HTTP port */
20
WireMockRule(int port);
21
22
/** Constructor with HTTP and HTTPS ports */
23
WireMockRule(int port, Integer httpsPort);
24
25
/** Constructor with custom options */
26
WireMockRule(Options options);
27
28
/** Constructor with options and failure behavior */
29
WireMockRule(Options options, boolean failOnUnmatchedRequests);
30
31
// TestRule Implementation
32
Statement apply(Statement base, Description description);
33
34
// Lifecycle Hooks (protected)
35
/** Called before each test method */
36
protected void before();
37
38
/** Called after each test method */
39
protected void after();
40
}
41
42
/**
43
* JUnit 4 class rule for class-level server lifecycle
44
*/
45
class WireMockClassRule extends WireMockServer implements MethodRule, TestRule {
46
// Constructors (same as WireMockRule)
47
WireMockClassRule();
48
WireMockClassRule(int port);
49
WireMockClassRule(int port, Integer httpsPort);
50
WireMockClassRule(Options options);
51
52
// TestRule Implementation
53
Statement apply(Statement base, Description description);
54
55
// MethodRule Implementation
56
Statement apply(Statement base, FrameworkMethod method, Object target);
57
58
// Lifecycle Hooks
59
protected void before();
60
protected void after();
61
}
62
63
/**
64
* Core stubbing interface for test integration
65
*/
66
interface Stubbing {
67
// Stub Management
68
void givenThat(MappingBuilder mappingBuilder);
69
void stubFor(MappingBuilder mappingBuilder);
70
void editStub(MappingBuilder mappingBuilder);
71
void removeStub(MappingBuilder mappingBuilder);
72
void removeStub(StubMapping stubMapping);
73
void removeStub(UUID id);
74
75
// Stub Retrieval
76
ListStubMappingsResult getStubMappings();
77
SingleStubMappingResult getSingleStubMapping(UUID id);
78
ListStubMappingsResult findStubMappingsByMetadata(StringValuePattern pattern);
79
80
// Request Verification
81
void verify(RequestPatternBuilder requestPatternBuilder);
82
void verify(int count, RequestPatternBuilder requestPatternBuilder);
83
void verify(CountMatchingStrategy strategy, RequestPatternBuilder requestPatternBuilder);
84
85
// Request Inspection
86
List<LoggedRequest> findAll(RequestPatternBuilder requestPatternBuilder);
87
List<ServeEvent> getAllServeEvents();
88
List<LoggedRequest> findAllUnmatchedRequests();
89
90
// Near Miss Analysis
91
List<NearMiss> findNearMissesFor(LoggedRequest loggedRequest);
92
List<NearMiss> findAllNearMissesFor(RequestPattern requestPattern);
93
94
// Global Settings
95
void setGlobalFixedDelay(int milliseconds);
96
}
97
```
98
99
**Usage Examples:**
100
101
```java
102
import com.github.tomakehurst.wiremock.junit.WireMockRule;
103
import org.junit.Rule;
104
import org.junit.Test;
105
import static com.github.tomakehurst.wiremock.client.WireMock.*;
106
107
public class MyServiceTest {
108
109
@Rule
110
public WireMockRule wireMockRule = new WireMockRule(8089);
111
112
@Test
113
public void testApiCall() {
114
// Setup stub
115
stubFor(get(urlEqualTo("/api/data"))
116
.willReturn(aResponse()
117
.withStatus(200)
118
.withBody("test data")));
119
120
// Execute test
121
String result = myService.fetchData("http://localhost:8089/api/data");
122
123
// Verify
124
assertEquals("test data", result);
125
verify(getRequestedFor(urlEqualTo("/api/data")));
126
}
127
}
128
129
// Class-level rule example
130
public class IntegrationTest {
131
132
@ClassRule
133
public static WireMockClassRule wireMock = new WireMockClassRule(8089);
134
135
@Rule
136
public WireMockClassRule instanceRule = wireMock;
137
138
@Test
139
public void testOne() {
140
instanceRule.stubFor(get(urlEqualTo("/test1"))
141
.willReturn(ok()));
142
}
143
144
@Test
145
public void testTwo() {
146
instanceRule.stubFor(get(urlEqualTo("/test2"))
147
.willReturn(ok()));
148
}
149
}
150
```
151
152
### JUnit 5 Integration
153
154
Modern JUnit Jupiter extension with declarative configuration and parameter injection support.
155
156
```java { .api }
157
/**
158
* JUnit 5 extension for WireMock integration
159
*/
160
class WireMockExtension extends DslWrapper implements
161
ParameterResolver, BeforeEachCallback, BeforeAllCallback,
162
AfterEachCallback, AfterAllCallback {
163
164
// Static Factory Methods
165
/** Create extension builder */
166
static Builder newInstance();
167
168
/** Alias for newInstance() */
169
static Builder extensionOptions();
170
171
// Lifecycle Callbacks
172
void beforeAll(ExtensionContext context);
173
void beforeEach(ExtensionContext context);
174
void afterEach(ExtensionContext context);
175
void afterAll(ExtensionContext context);
176
177
// Parameter Resolution
178
boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext);
179
Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext);
180
181
// Extension Hooks (protected)
182
/** Called before all tests in class */
183
protected void onBeforeAll(ExtensionContext context);
184
185
/** Called before each test method */
186
protected void onBeforeEach(ExtensionContext context);
187
188
/** Called after each test method */
189
protected void onAfterEach(ExtensionContext context);
190
191
/** Called after all tests in class */
192
protected void onAfterAll(ExtensionContext context);
193
194
/**
195
* Builder for WireMockExtension configuration
196
*/
197
static class Builder {
198
/** Set server options */
199
Builder options(Options options);
200
201
/** Configure static DSL */
202
Builder configureStaticDsl(boolean configureStaticDsl);
203
204
/** Fail on unmatched requests */
205
Builder failOnUnmatchedRequests(boolean failOnUnmatchedRequests);
206
207
/** Enable proxy mode */
208
Builder proxyMode(boolean proxyMode);
209
210
/** Reset server between tests */
211
Builder resetOnEachTest(boolean resetOnEachTest);
212
213
/** Build configured extension */
214
WireMockExtension build();
215
}
216
}
217
218
/**
219
* Declarative annotation for WireMock test configuration
220
*/
221
@Target(ElementType.TYPE)
222
@Retention(RetentionPolicy.RUNTIME)
223
@ExtendWith(WireMockExtension.class)
224
public @interface WireMockTest {
225
/** Enable extension scanning */
226
boolean extensionScanningEnabled() default false;
227
228
/** HTTP port (0 for dynamic) */
229
int httpPort() default 0;
230
231
/** Enable HTTPS */
232
boolean httpsEnabled() default false;
233
234
/** HTTPS port (0 for dynamic) */
235
int httpsPort() default 0;
236
237
/** Enable proxy mode */
238
boolean proxyMode() default false;
239
}
240
241
/**
242
* Runtime information about WireMock server for parameter injection
243
*/
244
class WireMockRuntimeInfo {
245
/** Get HTTP port */
246
int getHttpPort();
247
248
/** Get HTTPS port */
249
int getHttpsPort();
250
251
/** Check if HTTP is enabled */
252
boolean isHttpEnabled();
253
254
/** Check if HTTPS is enabled */
255
boolean isHttpsEnabled();
256
257
/** Get HTTP base URL */
258
String getHttpBaseUrl();
259
260
/** Get HTTPS base URL */
261
String getHttpsBaseUrl();
262
263
/** Get configured WireMock client */
264
WireMock getWireMock();
265
}
266
```
267
268
**Usage Examples:**
269
270
```java
271
import com.github.tomakehurst.wiremock.junit5.WireMockExtension;
272
import com.github.tomakehurst.wiremock.junit5.WireMockTest;
273
import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo;
274
import org.junit.jupiter.api.Test;
275
import org.junit.jupiter.api.extension.RegisterExtension;
276
import static com.github.tomakehurst.wiremock.client.WireMock.*;
277
278
// Declarative configuration
279
@WireMockTest(httpPort = 8089, httpsEnabled = true)
280
class DeclarativeTest {
281
282
@Test
283
void testWithRuntimeInfo(WireMockRuntimeInfo wmRuntimeInfo) {
284
// Setup stub
285
stubFor(get("/api/test")
286
.willReturn(ok("Hello World")));
287
288
// Use runtime info
289
String baseUrl = wmRuntimeInfo.getHttpBaseUrl();
290
assertEquals("http://localhost:8089", baseUrl);
291
292
// Execute and verify
293
String result = callApi(baseUrl + "/api/test");
294
assertEquals("Hello World", result);
295
verify(getRequestedFor(urlEqualTo("/api/test")));
296
}
297
}
298
299
// Programmatic configuration
300
class ProgrammaticTest {
301
302
@RegisterExtension
303
static WireMockExtension wm = WireMockExtension.newInstance()
304
.options(wireMockConfig()
305
.port(8089)
306
.httpsPort(8443)
307
.keystorePath("test-keystore.jks"))
308
.failOnUnmatchedRequests(true)
309
.build();
310
311
@Test
312
void testWithExtension() {
313
wm.stubFor(get("/api/secure")
314
.willReturn(ok("Secure response")));
315
316
// Test logic here
317
wm.verify(getRequestedFor(urlEqualTo("/api/secure")));
318
}
319
}
320
321
// Per-test lifecycle
322
class PerTestTest {
323
324
@RegisterExtension
325
WireMockExtension wm = WireMockExtension.newInstance()
326
.resetOnEachTest(true)
327
.build();
328
329
@Test
330
void testOne(WireMockRuntimeInfo wmRuntimeInfo) {
331
wm.stubFor(get("/test1").willReturn(ok()));
332
// Test automatically resets after this method
333
}
334
335
@Test
336
void testTwo(WireMockRuntimeInfo wmRuntimeInfo) {
337
wm.stubFor(get("/test2").willReturn(ok()));
338
// Previous test's stubs are automatically cleared
339
}
340
}
341
```
342
343
### DslWrapper Implementation
344
345
Administrative wrapper that combines admin and stubbing functionality for test integration.
346
347
```java { .api }
348
/**
349
* Wrapper combining Admin and Stubbing interfaces for test integration
350
*/
351
class DslWrapper implements Admin, Stubbing {
352
/** Constructor with admin instance */
353
DslWrapper(Admin admin);
354
355
// Delegates to both Admin and Stubbing interfaces
356
// Includes all methods from:
357
// - Admin interface (server management, request journal, scenarios)
358
// - Stubbing interface (stub management, verification, inspection)
359
360
// Additional Test Utilities
361
/** Get server port */
362
int getPort();
363
364
/** Get server options */
365
Options getOptions();
366
367
/** Check if server is running */
368
boolean isRunning();
369
370
/** Get base URL for HTTP */
371
String baseUrl();
372
373
/** Get base URL for HTTPS */
374
String httpsBaseUrl();
375
}
376
```
377
378
### Legacy JUnit 4 Support
379
380
```java { .api }
381
/**
382
* @deprecated Legacy static rule - use WireMockClassRule instead
383
*/
384
@Deprecated
385
class WireMockStaticRule implements MethodRule {
386
WireMockStaticRule();
387
WireMockStaticRule(int port);
388
WireMockStaticRule(Options options);
389
390
Statement apply(Statement base, FrameworkMethod method, Object target);
391
}
392
```
393
394
### Integration Best Practices
395
396
**JUnit 4 vs JUnit 5 Decision Matrix:**
397
398
| Feature | JUnit 4 | JUnit 5 |
399
|---------|---------|---------|
400
| Lifecycle Management | `@Rule`, `@ClassRule` | `@ExtendWith`, `@WireMockTest` |
401
| Configuration | Constructor parameters | Builder pattern + annotation |
402
| Parameter Injection | Not supported | `WireMockRuntimeInfo` injection |
403
| Declarative Config | Not supported | `@WireMockTest` annotation |
404
| Extension Points | Override `before()`/`after()` | Override lifecycle callbacks |
405
| Static DSL Config | Manual | Automatic option |
406
407
**Usage Recommendations:**
408
409
```java
410
// For simple tests - use declarative approach
411
@WireMockTest
412
class SimpleTest {
413
@Test
414
void test(WireMockRuntimeInfo wmInfo) {
415
// Test logic with automatic WireMock setup
416
}
417
}
418
419
// For complex configuration - use programmatic approach
420
class ComplexTest {
421
@RegisterExtension
422
static WireMockExtension wm = WireMockExtension.newInstance()
423
.options(wireMockConfig()
424
.port(8089)
425
.httpsPort(8443)
426
.extensionScanningEnabled(true)
427
.extensions("com.example.CustomTransformer"))
428
.failOnUnmatchedRequests(true)
429
.build();
430
}
431
432
// For class-level setup with method-level cleanup
433
class MixedLifecycleTest {
434
@RegisterExtension
435
static WireMockExtension wm = WireMockExtension.newInstance()
436
.resetOnEachTest(false) // Keep stubs across tests
437
.build();
438
439
@BeforeAll
440
static void setupCommonStubs() {
441
wm.stubFor(get("/common").willReturn(ok()));
442
}
443
444
@AfterEach
445
void cleanupTestSpecificStubs() {
446
// Clean up only test-specific stubs
447
}
448
}
449
```