Added tests for visitor pattern

This commit is contained in:
Jeroen Meulemeester 2015-12-30 19:48:26 +01:00
parent 997bfba3b2
commit 09d3a82884
10 changed files with 345 additions and 0 deletions

View File

@ -14,5 +14,10 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,25 @@
package com.iluwatar.visitor;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.verify;
/**
* Date: 12/30/15 - 19:45 PM
*
* @author Jeroen Meulemeester
*/
public class CommanderTest extends UnitTest<Commander> {
/**
* Create a new test instance for the given {@link Commander}
*/
public CommanderTest() {
super(Commander::new);
}
@Override
void verifyVisit(Commander unit, UnitVisitor mockedVisitor) {
verify(mockedVisitor).visitCommander(eq(unit));
}
}

View File

@ -0,0 +1,24 @@
package com.iluwatar.visitor;
import java.util.Optional;
/**
* Date: 12/30/15 - 18:43 PM
*
* @author Jeroen Meulemeester
*/
public class CommanderVisitorTest extends VisitorTest<CommanderVisitor> {
/**
* Create a new test instance for the given visitor
*/
public CommanderVisitorTest() {
super(
new CommanderVisitor(),
Optional.of("Good to see you commander"),
Optional.empty(),
Optional.empty()
);
}
}

View File

@ -0,0 +1,25 @@
package com.iluwatar.visitor;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.verify;
/**
* Date: 12/30/15 - 19:45 PM
*
* @author Jeroen Meulemeester
*/
public class SergeantTest extends UnitTest<Sergeant> {
/**
* Create a new test instance for the given {@link Sergeant}
*/
public SergeantTest() {
super(Sergeant::new);
}
@Override
void verifyVisit(Sergeant unit, UnitVisitor mockedVisitor) {
verify(mockedVisitor).visitSergeant(eq(unit));
}
}

View File

@ -0,0 +1,24 @@
package com.iluwatar.visitor;
import java.util.Optional;
/**
* Date: 12/30/15 - 18:36 PM
*
* @author Jeroen Meulemeester
*/
public class SergeantVisitorTest extends VisitorTest<SergeantVisitor> {
/**
* Create a new test instance for the given visitor
*/
public SergeantVisitorTest() {
super(
new SergeantVisitor(),
Optional.empty(),
Optional.of("Hello sergeant"),
Optional.empty()
);
}
}

View File

@ -0,0 +1,25 @@
package com.iluwatar.visitor;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.verify;
/**
* Date: 12/30/15 - 19:45 PM
*
* @author Jeroen Meulemeester
*/
public class SoldierTest extends UnitTest<Soldier> {
/**
* Create a new test instance for the given {@link Soldier}
*/
public SoldierTest() {
super(Soldier::new);
}
@Override
void verifyVisit(Soldier unit, UnitVisitor mockedVisitor) {
verify(mockedVisitor).visitSoldier(eq(unit));
}
}

View File

@ -0,0 +1,24 @@
package com.iluwatar.visitor;
import java.util.Optional;
/**
* Date: 12/30/15 - 18:59 PM
*
* @author Jeroen Meulemeester
*/
public class SoldierVisitorTest extends VisitorTest<SoldierVisitor> {
/**
* Create a new test instance for the given visitor
*/
public SoldierVisitorTest() {
super(
new SoldierVisitor(),
Optional.empty(),
Optional.empty(),
Optional.of("Greetings soldier")
);
}
}

View File

@ -0,0 +1,53 @@
package com.iluwatar.visitor;
import org.junit.After;
import org.junit.Before;
import java.io.PrintStream;
import static org.mockito.Mockito.mock;
/**
* Date: 12/10/15 - 8:37 PM
*
* @author Jeroen Meulemeester
*/
public abstract class StdOutTest {
/**
* The mocked standard out {@link PrintStream}, required since some actions don't have any
* influence on accessible objects, except for writing to std-out using {@link System#out}
*/
private final PrintStream stdOutMock = mock(PrintStream.class);
/**
* Keep the original std-out so it can be restored after the test
*/
private final PrintStream stdOutOrig = System.out;
/**
* Inject the mocked std-out {@link PrintStream} into the {@link System} class before each test
*/
@Before
public void setUp() {
System.setOut(this.stdOutMock);
}
/**
* Removed the mocked std-out {@link PrintStream} again from the {@link System} class
*/
@After
public void tearDown() {
System.setOut(this.stdOutOrig);
}
/**
* Get the mocked stdOut {@link PrintStream}
*
* @return The stdOut print stream mock, renewed before each test
*/
final PrintStream getStdOutMock() {
return this.stdOutMock;
}
}

View File

@ -0,0 +1,60 @@
package com.iluwatar.visitor;
import org.junit.Test;
import java.util.Arrays;
import java.util.function.Function;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
/**
* Date: 12/30/15 - 18:59 PM
*
* @author Jeroen Meulemeester
*/
public abstract class UnitTest<U extends Unit> {
/**
* Factory to create new instances of the tested unit
*/
private final Function<Unit[], U> factory;
/**
* Create a new test instance for the given unit type {@link U}
*
* @param factory Factory to create new instances of the tested unit
*/
public UnitTest(final Function<Unit[], U> factory) {
this.factory = factory;
}
@Test
public void testAccept() throws Exception {
final Unit[] children = new Unit[5];
Arrays.setAll(children, (i) -> mock(Unit.class));
final U unit = this.factory.apply(children);
final UnitVisitor visitor = mock(UnitVisitor.class);
unit.accept(visitor);
verifyVisit(unit, visitor);
for (final Unit child : children) {
verify(child).accept(eq(visitor));
}
verifyNoMoreInteractions(children);
verifyNoMoreInteractions(visitor);
}
/**
* Verify if the correct visit method is called on the mock, depending on the tested instance
*
* @param unit The tested unit instance
* @param mockedVisitor The mocked {@link UnitVisitor} who should have gotten a visit by the unit
*/
abstract void verifyVisit(final U unit, final UnitVisitor mockedVisitor);
}

View File

@ -0,0 +1,80 @@
package com.iluwatar.visitor;
import org.junit.Test;
import java.util.Optional;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
/**
* Date: 12/30/15 - 18:59 PM
*
* @author Jeroen Meulemeester
*/
public abstract class VisitorTest<V extends UnitVisitor> extends StdOutTest {
/**
* The tested visitor instance
*/
private final V visitor;
/**
* The optional expected response when being visited by a commander
*/
private final Optional<String> commanderResponse;
/**
* The optional expected response when being visited by a sergeant
*/
private final Optional<String> sergeantResponse;
/**
* The optional expected response when being visited by a soldier
*/
private final Optional<String> soldierResponse;
/**
* Create a new test instance for the given visitor
*
* @param commanderResponse The optional expected response when being visited by a commander
* @param sergeantResponse The optional expected response when being visited by a sergeant
* @param soldierResponse The optional expected response when being visited by a soldier
*/
public VisitorTest(final V visitor, final Optional<String> commanderResponse,
final Optional<String> sergeantResponse, final Optional<String> soldierResponse) {
this.visitor = visitor;
this.commanderResponse = commanderResponse;
this.sergeantResponse = sergeantResponse;
this.soldierResponse = soldierResponse;
}
@Test
public void testVisitCommander() {
this.visitor.visitCommander(new Commander());
if (this.commanderResponse.isPresent()) {
verify(getStdOutMock()).println(this.commanderResponse.get());
}
verifyNoMoreInteractions(getStdOutMock());
}
@Test
public void testVisitSergeant() {
this.visitor.visitSergeant(new Sergeant());
if (this.sergeantResponse.isPresent()) {
verify(getStdOutMock()).println(this.sergeantResponse.get());
}
verifyNoMoreInteractions(getStdOutMock());
}
@Test
public void testVisitSoldier() {
this.visitor.visitSoldier(new Soldier());
if (this.soldierResponse.isPresent()) {
verify(getStdOutMock()).println(this.soldierResponse.get());
}
verifyNoMoreInteractions(getStdOutMock());
}
}