Skip to content

Commit 09aa177

Browse files
authored
Merge pull request #1 from marion-an/exercise_4
Exercise 4
2 parents af8ae74 + da11b75 commit 09aa177

File tree

6 files changed

+283
-12
lines changed

6 files changed

+283
-12
lines changed

03-messages/Documentation.md

+15-10
Original file line numberDiff line numberDiff line change
@@ -16,29 +16,34 @@
1616
- T4: ``messages`` contains the same ``Message`` object multiple times
1717

1818
## B. Content of invocations - ``ArgumentCaptor``
19-
19+
The content of ``Message`` objects which are passed to ``sendMessage(String receiver, String message)``is verified by using an argumentCaptor
2020
- T5: one message is sent, where the content is verified
2121
- T6: ``Message`` to be sent has ``null`` as receiver and content
2222
- T7: multiple messages are sent, where the content is verified
2323

2424

2525
## C. Content of invocations—Increasing observability
26+
The content of ``Message`` objects which are passed to ``sendMessage(String receiver, String message)``is verified by adding the ``Message`` objects to a list which is returned
2627
- T8: one message is sent, where the content is verified
2728
- T9: ``Message`` to be sent has ``null`` as receiver and content
2829
- T10: multiple messages are sent, where the content is verified
2930
- T11: ``messages`` is empty
3031

3132
## D. Comparison
3233

33-
### Advantages
34+
### ArgumentCaptor
35+
#### Advantages
36+
- Verify which arguments are passed to ``sendMessage(String receiver, String message)`` without needing to change the source code
37+
- Increases understandability as arguments expected are explicitly stated in the test
38+
39+
#### Disadvantages
40+
- Requires setup
3441

35-
| ArgumentCaptor | Increase Observability |
36-
|----------------------------------------------------------------------------------------------------------------------------|------------------|
37-
| Verfify which arguments are passsed to ``sendMessage(String receiver, String message)`` without needing to change the code | Increases testability |
38-
| Increases understandability as arguments expected are explictly stated in the test | |
42+
### Increase Observability
43+
##### Advantages
44+
- Makes it easier to assert the behaviour of ``sendMessage(String receiver, String message)``
45+
- Increases testability
3946

47+
##### Disadvantages
48+
- Production code has to be modified
4049

41-
### Disadvantages
42-
| ArgumentCaptor | Increase Observability |
43-
|----------------|------------------------------------|
44-
| Requires setup | Production code has to be modified |

04-e_shop/Assets/test_results.png

36.8 KB
Loading

04-e_shop/Documentation.md

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Messages
2+
3+
## A. Number of invocation
4+
5+
- In the book it's stated that entities should not be mocked. Therefore, the ``Order`` objects are instantiated.
6+
- The implementation of the ``e-shop`` follows the Hexagonal Architecture. Therefore, the ``EventPublisher`` does not depend on low-level modules, instead it depends on an abstraction, the ``EventListener``. The ``EventListener`` is a port and both the ``InventoryManager`` and the ``ÈmailNotificationService`` are adapters.
7+
- In order to mock the ``EventListener listeners`` a constructor is added to the class where this dependency will get injected.
8+
-
9+
- T1: test to verify that ``listener.onOrderPlaced(order)`` gets called the right number of times
10+
11+
- a boundary of the ``publishOrderToAllListeners`` method is that ``listeners`` contains one element and the ``listener.onOrderPlaced(order)`` is called once
12+
- T2: ``listeners`` is empty
13+
- T3: ``listeners`` contains one element
14+
15+
## B. Content of invocations - ``ArgumentCaptor``
16+
The content of ``Order`` object which is passed to ``listener.onOrderPlaced(order)``is verified by using an argumentCaptor where it was differentiated between an ``Order`` object and ``null``
17+
- T4: one order is placed, where the content is verified
18+
- T5: ``Order`` to be placed is ``null``
19+
- T6: one order is placed and there are multiple listeners, where the content is verified
20+
21+
22+
## C. Content of invocations—Increasing observability
23+
The content of ``Order`` object which is passed to ``listener.onOrderPlaced(order)``is verified by adding the ``Order`` object to a list where it was differentiated between an ``Order`` object and ``null``
24+
- T7: one order is placed, where the content of the order is verified
25+
- T8: ``Order`` to be published is ``null``
26+
- T9: multiple ``listeners`` where the order content is verified
27+
28+
It was also verified that no content is present when there is no ``listener`` present
29+
- T10: no ``listeners`` are present, verify that no order is placed
30+
31+
## D. Comparison
32+
33+
### Advantages
34+
### ArgumentCaptor
35+
#### Advantages
36+
- Verify which arguments are passed to ``onOrderPlaced(Order order)`` without needing to change the source code
37+
- Suitable to test void method
38+
- Increases understandability as arguments expected are explicitly stated in the test
39+
40+
#### Disadvantages
41+
- Requires setup
42+
43+
### Increase Observability
44+
##### Advantages
45+
- Increases testability
46+
- Makes test methods simpler
47+
48+
##### Disadvantages
49+
- Production code has to be modified
50+

04-e_shop/pom.xml

+6
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@
3737
<version>4.5.1</version>
3838
<scope>test</scope>
3939
</dependency>
40+
<dependency>
41+
<groupId>org.mockito</groupId>
42+
<artifactId>mockito-junit-jupiter</artifactId>
43+
<version>4.5.1</version>
44+
<scope>test</scope>
45+
</dependency>
4046

4147
</dependencies>
4248

04-e_shop/src/main/java/EventPublisher.java

+10-2
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,23 @@
22
import java.util.List;
33

44
public class EventPublisher {
5-
private List<EventListener> listeners = new ArrayList<>();
5+
private final List<EventListener> listeners;
6+
7+
public EventPublisher(List<EventListener> listeners) {
8+
this.listeners = listeners;
9+
}
10+
611

712
public void subscribe(EventListener listener) {
813
listeners.add(listener);
914
}
1015

11-
public void publishOrderToAllListeners(Order order) {
16+
public List<Order> publishOrderToAllListeners(Order order) {
17+
List<Order> published = new ArrayList<>();
1218
for (EventListener listener : listeners) {
1319
listener.onOrderPlaced(order);
20+
published.add(order);
1421
}
22+
return published;
1523
}
1624
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
import org.junit.jupiter.api.Test;
2+
import org.junit.jupiter.api.extension.ExtendWith;
3+
import org.mockito.ArgumentCaptor;
4+
import org.mockito.Mock;
5+
import org.mockito.junit.jupiter.MockitoExtension;
6+
7+
import java.util.ArrayList;
8+
import java.util.List;
9+
10+
import static org.mockito.Mockito.*;
11+
12+
import static org.junit.jupiter.api.Assertions.*;
13+
14+
@ExtendWith(MockitoExtension.class)
15+
class EventPublisherTest {
16+
17+
@Mock
18+
EventListener listener;
19+
20+
@Test
21+
void numberOfInvocationA() {
22+
List<EventListener> listeners = new ArrayList<>();
23+
EventPublisher eventPublisher = new EventPublisher(listeners);
24+
25+
eventPublisher.subscribe(listener);
26+
eventPublisher.subscribe(listener);
27+
eventPublisher.subscribe(listener);
28+
29+
Order order = new Order("orderId", 1);
30+
31+
doNothing().when(listener).onOrderPlaced(order);
32+
33+
eventPublisher.publishOrderToAllListeners(order);
34+
35+
verify(listener, times(3)).onOrderPlaced(order);
36+
}
37+
38+
@Test
39+
void noInvocationA() {
40+
List<EventListener> listeners = new ArrayList<>();
41+
EventPublisher eventPublisher = new EventPublisher(listeners);
42+
43+
Order order = new Order("orderId", 1);
44+
45+
46+
eventPublisher.publishOrderToAllListeners(order);
47+
48+
verify(listener, never()).onOrderPlaced(any());
49+
}
50+
51+
@Test
52+
void onInvocationA() {
53+
List<EventListener> listeners = new ArrayList<>();
54+
EventPublisher eventPublisher = new EventPublisher(listeners);
55+
56+
eventPublisher.subscribe(listener);
57+
58+
Order order = new Order("orderId", 1);
59+
60+
doNothing().when(listener).onOrderPlaced(order);
61+
62+
eventPublisher.publishOrderToAllListeners(order);
63+
64+
verify(listener, times(1)).onOrderPlaced(order);
65+
}
66+
67+
@Test
68+
void rightOrderContentB() {
69+
List<EventListener> listeners = new ArrayList<>();
70+
EventPublisher eventPublisher = new EventPublisher(listeners);
71+
72+
eventPublisher.subscribe(listener);
73+
74+
Order order = new Order("order1", 1.234);
75+
76+
doNothing().when(listener).onOrderPlaced(any());
77+
78+
eventPublisher.publishOrderToAllListeners(order);
79+
80+
ArgumentCaptor<Order> receiveCaptor = ArgumentCaptor.forClass(Order.class);
81+
82+
verify(listener).onOrderPlaced(receiveCaptor.capture());
83+
84+
assertEquals("order1", receiveCaptor.getValue().getOrderId());
85+
assertEquals(1.234, receiveCaptor.getValue().getAmount());
86+
}
87+
88+
89+
@Test
90+
void nullContentB() {
91+
List<EventListener> listeners = new ArrayList<>();
92+
EventPublisher eventPublisher = new EventPublisher(listeners);
93+
94+
eventPublisher.subscribe(listener);
95+
96+
doNothing().when(listener).onOrderPlaced(any());
97+
98+
eventPublisher.publishOrderToAllListeners(null);
99+
100+
ArgumentCaptor<Order> receiveCaptor = ArgumentCaptor.forClass(Order.class);
101+
102+
verify(listener).onOrderPlaced(receiveCaptor.capture());
103+
104+
assertEquals(null, receiveCaptor.getValue());
105+
}
106+
107+
108+
@Test
109+
void multipleListenersB() {
110+
List<EventListener> listeners = new ArrayList<>();
111+
EventPublisher eventPublisher = new EventPublisher(listeners);
112+
113+
eventPublisher.subscribe(listener);
114+
eventPublisher.subscribe(listener);
115+
eventPublisher.subscribe(listener);
116+
117+
Order order = new Order("order1", 1.234);
118+
119+
doNothing().when(listener).onOrderPlaced(any());
120+
121+
eventPublisher.publishOrderToAllListeners(order);
122+
123+
ArgumentCaptor<Order> receiveCaptor = ArgumentCaptor.forClass(Order.class);
124+
125+
verify(listener, times(3)).onOrderPlaced(receiveCaptor.capture());
126+
127+
List<Order> receiver = receiveCaptor.getAllValues();
128+
129+
assertEquals(3, receiver.size());
130+
assertEquals(order, receiver.get(0));
131+
assertEquals(order, receiver.get(1));
132+
assertEquals(order, receiver.get(2));
133+
}
134+
135+
@Test
136+
void rightContentC() {
137+
List<EventListener> listeners = new ArrayList<>();
138+
EventPublisher eventPublisher = new EventPublisher(listeners);
139+
140+
eventPublisher.subscribe(listener);
141+
142+
Order order = new Order("order1", 1.234);
143+
144+
doNothing().when(listener).onOrderPlaced(any());
145+
146+
List<Order> published = eventPublisher.publishOrderToAllListeners(order);
147+
148+
assertEquals(1, published.size());
149+
assertEquals(order, published.get(0));
150+
assertEquals("order1", published.get(0).getOrderId());
151+
assertEquals(1.234, published.get(0).getAmount());
152+
}
153+
154+
@Test
155+
void nullContentC() {
156+
List<EventListener> listeners = new ArrayList<>();
157+
EventPublisher eventPublisher = new EventPublisher(listeners);
158+
159+
eventPublisher.subscribe(listener);
160+
161+
doNothing().when(listener).onOrderPlaced(any());
162+
163+
List<Order> published = eventPublisher.publishOrderToAllListeners(null);
164+
165+
assertEquals(1, published.size());
166+
assertEquals(null, published.get(0));
167+
}
168+
169+
@Test
170+
void multipleListenerC() {
171+
List<EventListener> listeners = new ArrayList<>();
172+
EventPublisher eventPublisher = new EventPublisher(listeners);
173+
174+
eventPublisher.subscribe(listener);
175+
eventPublisher.subscribe(listener);
176+
177+
Order order = new Order("order1", 1.234);
178+
179+
doNothing().when(listener).onOrderPlaced(any());
180+
181+
List<Order> published = eventPublisher.publishOrderToAllListeners(order);
182+
183+
assertEquals(2, published.size());
184+
assertEquals(order, published.get(0));
185+
assertEquals(order, published.get(1));
186+
}
187+
188+
@Test
189+
void noListenerC() {
190+
List<EventListener> listeners = new ArrayList<>();
191+
EventPublisher eventPublisher = new EventPublisher(listeners);
192+
193+
Order order = new Order("order1", 1.234);
194+
195+
196+
List<Order> published = eventPublisher.publishOrderToAllListeners(order);
197+
198+
assertEquals(0, published.size());
199+
}
200+
201+
202+
}

0 commit comments

Comments
 (0)