Skip to content

Commit 09d3a82

Browse files
committed
Added tests for visitor pattern
1 parent 997bfba commit 09d3a82

File tree

10 files changed

+345
-0
lines changed

10 files changed

+345
-0
lines changed

visitor/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,10 @@
1414
<artifactId>junit</artifactId>
1515
<scope>test</scope>
1616
</dependency>
17+
<dependency>
18+
<groupId>org.mockito</groupId>
19+
<artifactId>mockito-core</artifactId>
20+
<scope>test</scope>
21+
</dependency>
1722
</dependencies>
1823
</project>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.iluwatar.visitor;
2+
3+
import static org.mockito.Matchers.eq;
4+
import static org.mockito.Mockito.verify;
5+
6+
/**
7+
* Date: 12/30/15 - 19:45 PM
8+
*
9+
* @author Jeroen Meulemeester
10+
*/
11+
public class CommanderTest extends UnitTest<Commander> {
12+
13+
/**
14+
* Create a new test instance for the given {@link Commander}
15+
*/
16+
public CommanderTest() {
17+
super(Commander::new);
18+
}
19+
20+
@Override
21+
void verifyVisit(Commander unit, UnitVisitor mockedVisitor) {
22+
verify(mockedVisitor).visitCommander(eq(unit));
23+
}
24+
25+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.iluwatar.visitor;
2+
3+
import java.util.Optional;
4+
5+
/**
6+
* Date: 12/30/15 - 18:43 PM
7+
*
8+
* @author Jeroen Meulemeester
9+
*/
10+
public class CommanderVisitorTest extends VisitorTest<CommanderVisitor> {
11+
12+
/**
13+
* Create a new test instance for the given visitor
14+
*/
15+
public CommanderVisitorTest() {
16+
super(
17+
new CommanderVisitor(),
18+
Optional.of("Good to see you commander"),
19+
Optional.empty(),
20+
Optional.empty()
21+
);
22+
}
23+
24+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.iluwatar.visitor;
2+
3+
import static org.mockito.Matchers.eq;
4+
import static org.mockito.Mockito.verify;
5+
6+
/**
7+
* Date: 12/30/15 - 19:45 PM
8+
*
9+
* @author Jeroen Meulemeester
10+
*/
11+
public class SergeantTest extends UnitTest<Sergeant> {
12+
13+
/**
14+
* Create a new test instance for the given {@link Sergeant}
15+
*/
16+
public SergeantTest() {
17+
super(Sergeant::new);
18+
}
19+
20+
@Override
21+
void verifyVisit(Sergeant unit, UnitVisitor mockedVisitor) {
22+
verify(mockedVisitor).visitSergeant(eq(unit));
23+
}
24+
25+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.iluwatar.visitor;
2+
3+
import java.util.Optional;
4+
5+
/**
6+
* Date: 12/30/15 - 18:36 PM
7+
*
8+
* @author Jeroen Meulemeester
9+
*/
10+
public class SergeantVisitorTest extends VisitorTest<SergeantVisitor> {
11+
12+
/**
13+
* Create a new test instance for the given visitor
14+
*/
15+
public SergeantVisitorTest() {
16+
super(
17+
new SergeantVisitor(),
18+
Optional.empty(),
19+
Optional.of("Hello sergeant"),
20+
Optional.empty()
21+
);
22+
}
23+
24+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.iluwatar.visitor;
2+
3+
import static org.mockito.Matchers.eq;
4+
import static org.mockito.Mockito.verify;
5+
6+
/**
7+
* Date: 12/30/15 - 19:45 PM
8+
*
9+
* @author Jeroen Meulemeester
10+
*/
11+
public class SoldierTest extends UnitTest<Soldier> {
12+
13+
/**
14+
* Create a new test instance for the given {@link Soldier}
15+
*/
16+
public SoldierTest() {
17+
super(Soldier::new);
18+
}
19+
20+
@Override
21+
void verifyVisit(Soldier unit, UnitVisitor mockedVisitor) {
22+
verify(mockedVisitor).visitSoldier(eq(unit));
23+
}
24+
25+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.iluwatar.visitor;
2+
3+
import java.util.Optional;
4+
5+
/**
6+
* Date: 12/30/15 - 18:59 PM
7+
*
8+
* @author Jeroen Meulemeester
9+
*/
10+
public class SoldierVisitorTest extends VisitorTest<SoldierVisitor> {
11+
12+
/**
13+
* Create a new test instance for the given visitor
14+
*/
15+
public SoldierVisitorTest() {
16+
super(
17+
new SoldierVisitor(),
18+
Optional.empty(),
19+
Optional.empty(),
20+
Optional.of("Greetings soldier")
21+
);
22+
}
23+
24+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package com.iluwatar.visitor;
2+
3+
import org.junit.After;
4+
import org.junit.Before;
5+
6+
import java.io.PrintStream;
7+
8+
import static org.mockito.Mockito.mock;
9+
10+
/**
11+
* Date: 12/10/15 - 8:37 PM
12+
*
13+
* @author Jeroen Meulemeester
14+
*/
15+
public abstract class StdOutTest {
16+
17+
/**
18+
* The mocked standard out {@link PrintStream}, required since some actions don't have any
19+
* influence on accessible objects, except for writing to std-out using {@link System#out}
20+
*/
21+
private final PrintStream stdOutMock = mock(PrintStream.class);
22+
23+
/**
24+
* Keep the original std-out so it can be restored after the test
25+
*/
26+
private final PrintStream stdOutOrig = System.out;
27+
28+
/**
29+
* Inject the mocked std-out {@link PrintStream} into the {@link System} class before each test
30+
*/
31+
@Before
32+
public void setUp() {
33+
System.setOut(this.stdOutMock);
34+
}
35+
36+
/**
37+
* Removed the mocked std-out {@link PrintStream} again from the {@link System} class
38+
*/
39+
@After
40+
public void tearDown() {
41+
System.setOut(this.stdOutOrig);
42+
}
43+
44+
/**
45+
* Get the mocked stdOut {@link PrintStream}
46+
*
47+
* @return The stdOut print stream mock, renewed before each test
48+
*/
49+
final PrintStream getStdOutMock() {
50+
return this.stdOutMock;
51+
}
52+
53+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package com.iluwatar.visitor;
2+
3+
import org.junit.Test;
4+
5+
import java.util.Arrays;
6+
import java.util.function.Function;
7+
8+
import static org.mockito.Matchers.eq;
9+
import static org.mockito.Mockito.mock;
10+
import static org.mockito.Mockito.verify;
11+
import static org.mockito.Mockito.verifyNoMoreInteractions;
12+
13+
/**
14+
* Date: 12/30/15 - 18:59 PM
15+
*
16+
* @author Jeroen Meulemeester
17+
*/
18+
public abstract class UnitTest<U extends Unit> {
19+
20+
/**
21+
* Factory to create new instances of the tested unit
22+
*/
23+
private final Function<Unit[], U> factory;
24+
25+
/**
26+
* Create a new test instance for the given unit type {@link U}
27+
*
28+
* @param factory Factory to create new instances of the tested unit
29+
*/
30+
public UnitTest(final Function<Unit[], U> factory) {
31+
this.factory = factory;
32+
}
33+
34+
@Test
35+
public void testAccept() throws Exception {
36+
final Unit[] children = new Unit[5];
37+
Arrays.setAll(children, (i) -> mock(Unit.class));
38+
39+
final U unit = this.factory.apply(children);
40+
final UnitVisitor visitor = mock(UnitVisitor.class);
41+
unit.accept(visitor);
42+
verifyVisit(unit, visitor);
43+
44+
for (final Unit child : children) {
45+
verify(child).accept(eq(visitor));
46+
}
47+
48+
verifyNoMoreInteractions(children);
49+
verifyNoMoreInteractions(visitor);
50+
}
51+
52+
/**
53+
* Verify if the correct visit method is called on the mock, depending on the tested instance
54+
*
55+
* @param unit The tested unit instance
56+
* @param mockedVisitor The mocked {@link UnitVisitor} who should have gotten a visit by the unit
57+
*/
58+
abstract void verifyVisit(final U unit, final UnitVisitor mockedVisitor);
59+
60+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package com.iluwatar.visitor;
2+
3+
import org.junit.Test;
4+
5+
import java.util.Optional;
6+
7+
import static org.mockito.Mockito.verify;
8+
import static org.mockito.Mockito.verifyNoMoreInteractions;
9+
10+
/**
11+
* Date: 12/30/15 - 18:59 PM
12+
*
13+
* @author Jeroen Meulemeester
14+
*/
15+
public abstract class VisitorTest<V extends UnitVisitor> extends StdOutTest {
16+
17+
/**
18+
* The tested visitor instance
19+
*/
20+
private final V visitor;
21+
22+
/**
23+
* The optional expected response when being visited by a commander
24+
*/
25+
private final Optional<String> commanderResponse;
26+
27+
/**
28+
* The optional expected response when being visited by a sergeant
29+
*/
30+
private final Optional<String> sergeantResponse;
31+
32+
/**
33+
* The optional expected response when being visited by a soldier
34+
*/
35+
private final Optional<String> soldierResponse;
36+
37+
/**
38+
* Create a new test instance for the given visitor
39+
*
40+
* @param commanderResponse The optional expected response when being visited by a commander
41+
* @param sergeantResponse The optional expected response when being visited by a sergeant
42+
* @param soldierResponse The optional expected response when being visited by a soldier
43+
*/
44+
public VisitorTest(final V visitor, final Optional<String> commanderResponse,
45+
final Optional<String> sergeantResponse, final Optional<String> soldierResponse) {
46+
47+
this.visitor = visitor;
48+
this.commanderResponse = commanderResponse;
49+
this.sergeantResponse = sergeantResponse;
50+
this.soldierResponse = soldierResponse;
51+
}
52+
53+
@Test
54+
public void testVisitCommander() {
55+
this.visitor.visitCommander(new Commander());
56+
if (this.commanderResponse.isPresent()) {
57+
verify(getStdOutMock()).println(this.commanderResponse.get());
58+
}
59+
verifyNoMoreInteractions(getStdOutMock());
60+
}
61+
62+
@Test
63+
public void testVisitSergeant() {
64+
this.visitor.visitSergeant(new Sergeant());
65+
if (this.sergeantResponse.isPresent()) {
66+
verify(getStdOutMock()).println(this.sergeantResponse.get());
67+
}
68+
verifyNoMoreInteractions(getStdOutMock());
69+
}
70+
71+
@Test
72+
public void testVisitSoldier() {
73+
this.visitor.visitSoldier(new Soldier());
74+
if (this.soldierResponse.isPresent()) {
75+
verify(getStdOutMock()).println(this.soldierResponse.get());
76+
}
77+
verifyNoMoreInteractions(getStdOutMock());
78+
}
79+
80+
}

0 commit comments

Comments
 (0)