Skip to content

Commit b3d1c2b

Browse files
committed
Added tests for generic observer pattern
1 parent 3e20a2a commit b3d1c2b

File tree

6 files changed

+212
-1
lines changed

6 files changed

+212
-1
lines changed

observer/src/main/java/com/iluwatar/observer/generic/Observable.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ public void addObserver(O observer) {
2222
this.observers.add(observer);
2323
}
2424

25+
public void removeObserver(O observer) {
26+
this.observers.remove(observer);
27+
}
28+
2529
/**
2630
* Notify observers
2731
*/

observer/src/test/java/com/iluwatar/observer/StdOutTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public void tearDown() {
4747
*
4848
* @return The stdOut print stream mock, renewed before each test
4949
*/
50-
final PrintStream getStdOutMock() {
50+
protected final PrintStream getStdOutMock() {
5151
return this.stdOutMock;
5252
}
5353

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package com.iluwatar.observer.generic;
2+
3+
import com.iluwatar.observer.Hobbits;
4+
import com.iluwatar.observer.WeatherObserverTest;
5+
import com.iluwatar.observer.WeatherType;
6+
7+
import org.junit.runner.RunWith;
8+
import org.junit.runners.Parameterized;
9+
10+
import java.util.ArrayList;
11+
import java.util.Collection;
12+
13+
/**
14+
* Date: 12/27/15 - 12:07 PM
15+
*
16+
* @author Jeroen Meulemeester
17+
*/
18+
@RunWith(Parameterized.class)
19+
public class GHobbitsTest extends ObserverTest<GHobbits> {
20+
21+
@Parameterized.Parameters
22+
public static Collection<Object[]> data() {
23+
final ArrayList<Object[]> testData = new ArrayList<>();
24+
testData.add(new Object[]{WeatherType.SUNNY, "The happy hobbits bade in the warm sun."});
25+
testData.add(new Object[]{WeatherType.RAINY, "The hobbits look for cover from the rain."});
26+
testData.add(new Object[]{WeatherType.WINDY, "The hobbits hold their hats tightly in the windy weather."});
27+
testData.add(new Object[]{WeatherType.COLD, "The hobbits are shivering in the cold weather."});
28+
return testData;
29+
}
30+
31+
/**
32+
* Create a new test with the given weather and expected response
33+
*
34+
* @param weather The weather that should be unleashed on the observer
35+
* @param response The expected response from the observer
36+
*/
37+
public GHobbitsTest(final WeatherType weather, final String response) {
38+
super(weather, response, GHobbits::new);
39+
}
40+
41+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package com.iluwatar.observer.generic;
2+
3+
import com.iluwatar.observer.StdOutTest;
4+
import com.iluwatar.observer.WeatherObserver;
5+
import com.iluwatar.observer.WeatherType;
6+
7+
import org.junit.Test;
8+
import org.mockito.InOrder;
9+
10+
import static org.mockito.Mockito.inOrder;
11+
import static org.mockito.Mockito.mock;
12+
import static org.mockito.Mockito.verify;
13+
import static org.mockito.Mockito.verifyNoMoreInteractions;
14+
import static org.mockito.Mockito.verifyZeroInteractions;
15+
16+
/**
17+
* Date: 12/27/15 - 11:08 AM
18+
*
19+
* @author Jeroen Meulemeester
20+
*/
21+
public class GWeatherTest extends StdOutTest {
22+
23+
/**
24+
* Add a {@link WeatherObserver}, verify if it gets notified of a weather change, remove the
25+
* observer again and verify that there are no more notifications.
26+
*/
27+
@Test
28+
public void testAddRemoveObserver() {
29+
final Race observer = mock(Race.class);
30+
31+
final GWeather weather = new GWeather();
32+
weather.addObserver(observer);
33+
verifyZeroInteractions(observer);
34+
35+
weather.timePasses();
36+
verify(getStdOutMock()).println("The weather changed to rainy.");
37+
verify(observer).update(weather, WeatherType.RAINY);
38+
39+
weather.removeObserver(observer);
40+
weather.timePasses();
41+
verify(getStdOutMock()).println("The weather changed to windy.");
42+
43+
verifyNoMoreInteractions(observer, getStdOutMock());
44+
}
45+
46+
/**
47+
* Verify if the weather passes in the order of the {@link WeatherType}s
48+
*/
49+
@Test
50+
public void testTimePasses() {
51+
final Race observer = mock(Race.class);
52+
final GWeather weather = new GWeather();
53+
weather.addObserver(observer);
54+
55+
final InOrder inOrder = inOrder(observer, getStdOutMock());
56+
final WeatherType[] weatherTypes = WeatherType.values();
57+
for (int i = 1; i < 20; i++) {
58+
weather.timePasses();
59+
inOrder.verify(observer).update(weather, weatherTypes[i % weatherTypes.length]);
60+
}
61+
62+
verifyNoMoreInteractions(observer);
63+
}
64+
65+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package com.iluwatar.observer.generic;
2+
3+
import com.iluwatar.observer.StdOutTest;
4+
import com.iluwatar.observer.WeatherType;
5+
6+
import org.junit.Test;
7+
8+
import java.util.function.Supplier;
9+
10+
import static org.mockito.Mockito.verify;
11+
import static org.mockito.Mockito.verifyNoMoreInteractions;
12+
import static org.mockito.Mockito.verifyZeroInteractions;
13+
14+
/**
15+
* Date: 12/27/15 - 11:44 AM
16+
*
17+
* @author Jeroen Meulemeester
18+
*/
19+
public abstract class ObserverTest<O extends Observer> extends StdOutTest {
20+
21+
/**
22+
* The observer instance factory
23+
*/
24+
private final Supplier<O> factory;
25+
26+
/**
27+
* The weather type currently tested
28+
*/
29+
private final WeatherType weather;
30+
31+
/**
32+
* The expected response from the observer
33+
*/
34+
private final String response;
35+
36+
/**
37+
* Create a new test instance using the given parameters
38+
*
39+
* @param weather The weather currently being tested
40+
* @param response The expected response from the observer
41+
* @param factory The factory, used to create an instance of the tested observer
42+
*/
43+
ObserverTest(final WeatherType weather, final String response, final Supplier<O> factory) {
44+
this.weather = weather;
45+
this.response = response;
46+
this.factory = factory;
47+
}
48+
49+
/**
50+
* Verify if the weather has the expected influence on the observer
51+
*/
52+
@Test
53+
public void testObserver() {
54+
final O observer = this.factory.get();
55+
verifyZeroInteractions(getStdOutMock());
56+
57+
observer.update(null, this.weather);
58+
verify(getStdOutMock()).println(this.response);
59+
verifyNoMoreInteractions(getStdOutMock());
60+
}
61+
62+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package com.iluwatar.observer.generic;
2+
3+
import com.iluwatar.observer.WeatherType;
4+
5+
import org.junit.runner.RunWith;
6+
import org.junit.runners.Parameterized;
7+
8+
import java.util.ArrayList;
9+
import java.util.Collection;
10+
11+
/**
12+
* Date: 12/27/15 - 12:07 PM
13+
*
14+
* @author Jeroen Meulemeester
15+
*/
16+
@RunWith(Parameterized.class)
17+
public class OrcsTest extends ObserverTest<GOrcs> {
18+
19+
@Parameterized.Parameters
20+
public static Collection<Object[]> data() {
21+
final ArrayList<Object[]> testData = new ArrayList<>();
22+
testData.add(new Object[]{WeatherType.SUNNY, "The sun hurts the orcs' eyes."});
23+
testData.add(new Object[]{WeatherType.RAINY, "The orcs are dripping wet."});
24+
testData.add(new Object[]{WeatherType.WINDY, "The orc smell almost vanishes in the wind."});
25+
testData.add(new Object[]{WeatherType.COLD, "The orcs are freezing cold."});
26+
return testData;
27+
}
28+
29+
/**
30+
* Create a new test with the given weather and expected response
31+
*
32+
* @param weather The weather that should be unleashed on the observer
33+
* @param response The expected response from the observer
34+
*/
35+
public OrcsTest(final WeatherType weather, final String response) {
36+
super(weather, response, GOrcs::new);
37+
}
38+
39+
}

0 commit comments

Comments
 (0)