You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: service-stub/README.md
+50-34
Original file line number
Diff line number
Diff line change
@@ -2,26 +2,30 @@
2
2
title: "Service Stub Pattern in Java: Simplifying Testing with Stub Implementations"
3
3
shortTitle: Service Stub
4
4
description: "Explore the Service Stub design pattern in Java using a Sentiment Analysis example. Learn how stub implementations provide dummy services to facilitate testing and development."
5
-
category: Structural
5
+
category: Testing
6
6
language: en
7
7
tag:
8
+
- API design
8
9
- Decoupling
10
+
- Integration
11
+
- Microservices
12
+
- Testing
9
13
---
10
14
11
15
## Also known as
12
16
13
-
*Dummy Service
14
-
*Fake Service
17
+
* Service Mock
18
+
*Test Double
15
19
16
20
## Intent of Service Stub Pattern
17
21
18
-
The Service Stub pattern provides a lightweight, dummy implementation of an external service to allow testing or development without relying on the real service, which may be unavailable, slow, or resource-intensive.
22
+
Provide a lightweight, simplified implementation of a remote or external service to facilitate testing in isolation.
19
23
20
24
## Detailed Explanation of Service Stub Pattern with Real-World Example
21
25
22
26
Real-world example
23
27
24
-
> In this example, we simulate a **Sentiment Analysis Service**. The real implementation delays execution and randomly decides the sentiment. The stub implementation, on the other hand, quickly returns predefined responses based on input text ("good", "bad", or neutral), making it ideal for testing.
28
+
> A real-world analogy for the Service Stub pattern could be a flight simulator used to train pilots. Instead of learning to fly directly using a real airplane—which would be costly, dangerous, and often impractical—pilots initially practice within a simulator. This simulator provides predefined, realistic scenarios and reactions, enabling pilots to train safely, repeatedly, and predictably without the complexities and risks associated with actual flight operations. Similarly, a Service Stub provides controlled, predictable responses for external services during testing, simplifying and accelerating software development and testing processes.
25
29
26
30
In plain words
27
31
@@ -37,21 +41,24 @@ Sequence diagram
37
41
38
42
## Programmatic Example of Service Stub Pattern in Java
39
43
40
-
We define a `SentimentAnalysisService` interface and provide two implementations:
44
+
We demonstrate the Service Stub pattern using a simple sentiment analysis example. To illustrate this clearly, we define a common interface `SentimentAnalysisServer`and create two separate implementations:
41
45
42
-
1.**RealSentimentAnalysisServer**: Simulates a slow, random sentiment analysis system.
43
-
2.**StubSentimentAnalysisServer**: Returns a deterministic result based on input keywords.
46
+
**RealSentimentAnalysisServer**: Represents a slow, realistic sentiment analysis service, returning random sentiment results to simulate external complexity and latency.
47
+
48
+
**StubSentimentAnalysisServer**: Provides fast, deterministic results based on simple keyword matching, suitable for isolated testing without external dependencies.
49
+
50
+
### Step-by-step Example Implementation
51
+
52
+
First, define a common interface that both implementations will use:
44
53
45
-
### Example Implementation
46
-
Both the real service and the stub implement the interface below.
47
54
```java
48
55
publicinterfaceSentimentAnalysisServer {
49
56
StringanalyzeSentiment(Stringtext);
50
57
}
51
58
```
52
-
The real sentiment analysis class returns a random response for a given input and simulates the runtime by sleeping
53
-
the Thread for 5 seconds. The Supplier\<Integer\> allows injecting controlled sentiment values during testing, ensuring
54
-
deterministic outputs.
59
+
60
+
Next, we create a realistic implementation that simulates a slow, external service. It introduces a delay of 5 seconds and returns random sentiment results (`Positive`, `Negative`, or `Neutral`). For flexibility and easier testing, it allows injecting a custom sentiment supplier:
@@ -77,8 +84,9 @@ public class RealSentimentAnalysisServer implements SentimentAnalysisServer {
77
84
}
78
85
}
79
86
```
80
-
The stub implementation simulates the real sentiment analysis class and provides a deterministic output
81
-
for a given input. Additionally, its runtime is almost zero.
87
+
88
+
Then, we provide a simplified stub implementation designed specifically for testing purposes. It returns immediate and predictable results based on simple keyword detection. This enables tests to run quickly and consistently without relying on external factors:
@@ -95,9 +103,10 @@ public class StubSentimentAnalysisServer implements SentimentAnalysisServer {
95
103
}
96
104
}
97
105
}
98
-
99
106
```
100
-
Here is the main function of the App class (entry point to the program)
107
+
108
+
Finally, here's the main application logic illustrating how to use both implementations in practice. Notice the significant performance difference between the real and stub implementations:
109
+
101
110
```java
102
111
@Slf4j
103
112
publicstaticvoid main(String[] args) {
@@ -116,39 +125,46 @@ Here is the main function of the App class (entry point to the program)
116
125
LOGGER.info("The sentiment is: {}", sentiment);
117
126
}
118
127
```
119
-
## When to Use the Service Stub Pattern in Java
120
128
121
-
Use the Service Stub pattern when:
129
+
In summary, implementing a Service Stub involves creating a simplified substitute (`StubSentimentAnalysisServer`) for an actual external service (`RealSentimentAnalysisServer`). This approach allows your tests to run quickly and consistently by isolating them from external complexity and unpredictability.
130
+
131
+
## When to Use the Service Stub Pattern in Java
122
132
123
-
*Testing components that depend on external services.
124
-
*The real service is slow, unreliable, or unavailable.
125
-
*You need predictable, predefined responses.
126
-
*Developing offline without real service access.
133
+
*When testing systems with external or third-party service dependencies.
134
+
*In integration tests to isolate the service being tested from network or external dependencies.
135
+
*During development when the actual services are unavailable or unreliable.
136
+
*To speed up tests by avoiding calls to slower external systems.
127
137
128
138
## Real-World Applications of Service Stub Pattern in Java
129
139
130
-
*Simulating APIs (payments, recommendation systems) during testing.
131
-
*Bypassing external AI/ML models in tests.
132
-
*Simplifying integration testing.
140
+
*WireMock: Widely used in Java testing to stub HTTP-based external services.
141
+
*Mockito: Allows creating lightweight stubs for dependencies in unit testing.
142
+
*Spring Cloud Contract: Provides contracts and stub servers for services in microservices architectures.
133
143
134
144
## Benefits and Trade-offs of Service Stub Pattern
135
145
136
146
Benefits:
137
147
138
-
* Reduces dependencies.
139
-
* Provides predictable behavior.
140
-
* Speeds up testing.
148
+
* Simplifies testing by eliminating dependencies on external systems.
149
+
* Speeds up testing processes by removing latency from external network calls.
150
+
* Allows consistent, repeatable, and predictable testing scenarios.
151
+
* Enables parallel test execution, improving overall development productivity.
141
152
142
153
Trade-offs:
143
154
144
-
* Requires maintaining stub logic.
145
-
* May not fully represent real service behavior.
155
+
* Stubs need to be regularly updated to reflect changes in the actual external services.
156
+
* May introduce false confidence if stubs do not accurately represent external system behavior.
157
+
* Can lead to additional overhead and maintenance of stub configurations.
*[Adapter](https://java-design-patterns.com/patterns/adapter/): Service Stub may sometimes implement Adapter interfaces to mimic external dependencies in a test environment.
162
+
* Mock Object: Similar to Service Stub, but Mock Objects usually verify interactions explicitly, while Service Stubs primarily provide predefined responses without verification.
163
+
*[Proxy](https://java-design-patterns.com/patterns/proxy/): Both Service Stub and Proxy introduce intermediate objects to control access or communication with actual components, though Proxy typically manages access control and communication, while Service Stub specifically aims to isolate for testing.
151
164
152
165
## References and Credits
153
166
154
-
*[Martin Fowler: Test Stubs](https://martinfowler.com/articles/mocksArentStubs.html)
167
+
*[Continuous Delivery: Reliable Software Releases through Build, Test, and Deployment Automation](https://amzn.to/4bjhTSK)
168
+
*[Growing Object-Oriented Software, Guided by Tests](https://amzn.to/4dGfIuk)
0 commit comments