-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactoring Main to be more testable
Added tests for AgeGuesserUI as well.
- Loading branch information
Showing
6 changed files
with
155 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package com.dacklabs.ageguesser; | ||
|
||
public class AgeGuesserUI { | ||
private final ConsoleIO io; | ||
private final AgeGuesser guesser; | ||
|
||
public AgeGuesserUI(ConsoleIO io, AgeGuesser guesser) { | ||
this.io = io; | ||
this.guesser = guesser; | ||
} | ||
|
||
public void start() { | ||
io.printLine("I will guess your age, and you tell me if it was higher, lower, or yes."); | ||
boolean correct = false; | ||
while (!correct) { | ||
int guess = guesser.guess(); | ||
io.printLine(String.format("Are you %d years old? (possible answers: higher, lower, yes)", guess)); | ||
String answer = io.getUserInput().toLowerCase(); | ||
|
||
if (answer.contains("higher")) { | ||
guesser.addHint(HintDirection.HIGHER); | ||
} else if (answer.contains("lower")) { | ||
guesser.addHint(HintDirection.LOWER); | ||
} else if (answer.contains("yes")) { | ||
correct = true; | ||
} else { | ||
io.printLine(String.format("I didn't understand \"%s\". Try again", answer)); | ||
} | ||
} | ||
io.printLine(String.format("Hooray! I only needed %d hints!", guesser.hintsReceived())); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package com.dacklabs.ageguesser; | ||
|
||
public interface ConsoleIO { | ||
String getUserInput(); | ||
|
||
void printLine(String line); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,32 +1,8 @@ | ||
package com.dacklabs.ageguesser; | ||
|
||
import java.util.Scanner; | ||
|
||
import static com.dacklabs.ageguesser.HintDirection.HIGHER; | ||
import static com.dacklabs.ageguesser.HintDirection.LOWER; | ||
|
||
public class Main { | ||
public static void main(String[] args) { | ||
Scanner scanner = new Scanner(System.in); | ||
|
||
System.out.println("I will guess your age, and you tell me if it was higher, lower, or correct."); | ||
AgeGuesser guesser = new AgeGuesser(); | ||
boolean correct = false; | ||
while (!correct) { | ||
int guess = guesser.guess(); | ||
System.out.println(String.format("Are you %d years old? (possible answers: higher, lower, correct)", guess)); | ||
String answer = scanner.nextLine().toLowerCase(); | ||
|
||
if (answer.contains("higher")) { | ||
guesser.addHint(HIGHER); | ||
} else if (answer.contains("lower")) { | ||
guesser.addHint(LOWER); | ||
} else if (answer.contains("correct")) { | ||
correct = true; | ||
} else { | ||
System.out.println(String.format("I didn't understand \"%s\". Try again", answer)); | ||
} | ||
} | ||
System.out.println(String.format("Hooray! I only needed %d hints!", guesser.hintsReceived())); | ||
AgeGuesserUI ui = new AgeGuesserUI(new SysIO(), new AgeGuesser()); | ||
ui.start(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package com.dacklabs.ageguesser; | ||
|
||
import java.util.Scanner; | ||
|
||
public final class SysIO implements ConsoleIO { | ||
|
||
private final Scanner scanner = new Scanner(System.in); | ||
|
||
@Override | ||
public String getUserInput() { | ||
return scanner.nextLine(); | ||
} | ||
|
||
@Override | ||
public void printLine(String line) { | ||
System.out.println(line); | ||
} | ||
} |
66 changes: 66 additions & 0 deletions
66
src/test/java/com/dacklabs/ageguesser/AgeGuesserUITest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package com.dacklabs.ageguesser; | ||
|
||
import org.junit.Test; | ||
|
||
import static org.junit.Assert.*; | ||
|
||
public class AgeGuesserUITest { | ||
|
||
@Test | ||
public void uiGuessesAgeAndCelebratesIfCorrect() { | ||
FakeIO io = new FakeIO("yes"); | ||
AgeGuesser guesser = new AgeGuesser(); | ||
|
||
AgeGuesserUI ui = new AgeGuesserUI(io, guesser); | ||
ui.start(); | ||
|
||
assertEquals(3, io.output.size()); | ||
|
||
String expectedFirstLine = "I will guess your age"; | ||
String expectedSecondLine = String.format("Are you %d years old? ", guesser.guess()); | ||
String expectedThirdLine = "Hooray! I only needed 0 hints"; | ||
|
||
assertTrue("first message wasn't instructions", | ||
io.output.get(0).contains(expectedFirstLine)); | ||
|
||
assertTrue("second message doesn't contain the guess", | ||
io.output.get(1).contains(expectedSecondLine)); | ||
|
||
assertTrue("third message doesn't contain a count of guesses", | ||
io.output.get(2).contains(expectedThirdLine)); | ||
} | ||
|
||
@Test | ||
public void uiKeepsGuessingAgeUntilCorrect() { | ||
FakeIO io = new FakeIO("higher", "lower", "yes"); | ||
|
||
AgeGuesserUI ui = new AgeGuesserUI(io, new AgeGuesser()); | ||
ui.start(); | ||
|
||
assertEquals(5, io.output.size()); | ||
|
||
String ageQuestionRegex = "Are you \\d+ years old.*"; | ||
|
||
assertTrue(io.output.get(1).matches(ageQuestionRegex)); | ||
assertTrue(io.output.get(2).matches(ageQuestionRegex)); | ||
assertTrue(io.output.get(3).matches(ageQuestionRegex)); | ||
} | ||
|
||
@Test | ||
public void uiTellsUserWhenItGetsAnInvalidCommandAndContinues() { | ||
FakeIO io = new FakeIO("aljsfl;kasjdf", "yes"); | ||
|
||
AgeGuesserUI ui = new AgeGuesserUI(io, new AgeGuesser()); | ||
ui.start(); | ||
|
||
assertEquals(5, io.output.size()); | ||
|
||
String secondLine = io.output.get(2); | ||
String expectedSecondLine = "I didn't understand \"aljsfl;kasjdf\""; | ||
String lastLine = io.output.get(4); | ||
|
||
assertTrue("Expected invalid command message but got " + secondLine, secondLine.contains(expectedSecondLine)); | ||
assertTrue("Expected Hooray but got " + lastLine, lastLine.contains("Hooray!")); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package com.dacklabs.ageguesser; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
public class FakeIO implements ConsoleIO { | ||
|
||
private int lineIndex = 0; | ||
private final String[] lines; | ||
|
||
// This is public so the test can inspect it easily | ||
public final List<String> output = new ArrayList<>(); | ||
|
||
// lines are what will pretend to be coming from System.in | ||
public FakeIO(String... lines) { | ||
this.lines = lines; | ||
} | ||
|
||
@Override | ||
public String getUserInput() { | ||
// return the next line that was passed in | ||
return lines[lineIndex++]; | ||
} | ||
|
||
@Override | ||
public void printLine(String line) { | ||
// the SUT calls this, and we just record it for later inspection | ||
output.add(line); | ||
} | ||
} |