Here is what I eventually ended up with after numerous runs of the Tennis Kata.
Firstly, the code:
public class Game { private readonly Point _servicePoint = new Point(); private readonly Point _receiverPoint = new Point(); public string Score { get { if (_servicePoint.ToString().Equals(Point.FORTY) && (_receiverPoint.ToString().Equals(Point.FORTY))) { return "DEUCE"; } return string.Format("{0}-{1}", _servicePoint, _receiverPoint); } } public void ScoreToService() { _servicePoint.Score(_receiverPoint); } public void ScoreToReceiver() { _receiverPoint.Score(_servicePoint); } }
public class Point { public const string LOVE = "0"; public const string FIFTEEN = "15"; public const string THIRTY = "30"; public const string FORTY = "40"; public const string GAME = "GAME"; public const string ADVANTAGE = "ADV"; private string _score = LOVE; private DictionaryAnd the tests:> _pointMap; public Point() { BuildPointMap(); } public override string ToString() { return _score; } public void Score(Point opponentPoint) { _pointMap[_score].Invoke(opponentPoint); } private void BuildPointMap() { _pointMap = new Dictionary > { {Point.LOVE, o => { _score = Point.FIFTEEN; }}, {Point.FIFTEEN, o => { _score = Point.THIRTY; }}, {Point.THIRTY, o => { _score = Point.FORTY; }}, { Point.FORTY, o => { if (o.ToString().Equals(Point.FORTY)) { _score = ADVANTAGE; } else { _score = o.ToString().Equals(Point.ADVANTAGE) ? FORTY : GAME; } } }, {Point.ADVANTAGE, o => { _score = GAME; }}, {Point.GAME, o => { throw new ApplicationException("Game already completed!"); } } }; } }
[TestFixture] public class TestGame { [Test] public void NewGame_ShouldSetScore_0_0() { //---------------Set up test pack------------------- //---------------Assert Precondition---------------- //---------------Execute Test ---------------------- var game = new Game(); //---------------Test Result ----------------------- Assert.IsNotNull(game); Assert.AreEqual("0-0", game.Score); } [Test] public void ScoreToService_When_0_0_ShouldSetScore_15_0() { //---------------Set up test pack------------------- var game = new Game(); //---------------Assert Precondition---------------- Assert.AreEqual("0-0", game.Score); //---------------Execute Test ---------------------- game.ScoreToService(); //---------------Test Result ----------------------- Assert.AreEqual("15-0", game.Score); } [Test] public void ScoreToReceiver_When_0_0_ShouldSetScore_0_15() { //---------------Set up test pack------------------- var game = new Game(); //---------------Assert Precondition---------------- Assert.AreEqual("0-0", game.Score); //---------------Execute Test ---------------------- game.ScoreToReceiver(); //---------------Test Result ----------------------- Assert.AreEqual("0-15", game.Score); } [Test] public void ScoreToReceiver_When_15_15_ShouldSetScore_15_30() { //---------------Set up test pack------------------- var game = new Game(); game.ScoreToService(); game.ScoreToReceiver(); //---------------Assert Precondition---------------- Assert.AreEqual("15-15", game.Score); //---------------Execute Test ---------------------- game.ScoreToReceiver(); //---------------Test Result ----------------------- Assert.AreEqual("15-30", game.Score); } [Test] public void ScoreToService_When_40_15_ShouldSetScore_GAME_15() { //---------------Set up test pack------------------- var game = new Game(); game.ScoreToService(); game.ScoreToService(); game.ScoreToService(); game.ScoreToReceiver(); //---------------Assert Precondition---------------- Assert.AreEqual("40-15", game.Score); //---------------Execute Test ---------------------- game.ScoreToService(); //---------------Test Result ----------------------- Assert.AreEqual("GAME-15", game.Score); } [Test] public void ScoreToService_When_30_40_ShouldSetScore_DEUCE() { //---------------Set up test pack------------------- var game = new Game(); game.ScoreToService(); game.ScoreToService(); game.ScoreToReceiver(); game.ScoreToReceiver(); game.ScoreToReceiver(); //---------------Assert Precondition---------------- Assert.AreEqual("30-40", game.Score); //---------------Execute Test ---------------------- game.ScoreToService(); //---------------Test Result ----------------------- Assert.AreEqual("DEUCE", game.Score); } [Test] public void ScoreToService_When_DEUCE_ShouldSetScore_ADV_40() { //---------------Set up test pack------------------- var game = new Game(); game.ScoreToService(); game.ScoreToService(); game.ScoreToService(); game.ScoreToReceiver(); game.ScoreToReceiver(); game.ScoreToReceiver(); //---------------Assert Precondition---------------- Assert.AreEqual("DEUCE", game.Score); //---------------Execute Test ---------------------- game.ScoreToService(); //---------------Test Result ----------------------- Assert.AreEqual("ADV-40", game.Score); } [Test] public void ScoreToReceiver_When_40_ADV_ShouldSetScore_40_GAME() { //---------------Set up test pack------------------- var game = new Game(); game.ScoreToService(); game.ScoreToService(); game.ScoreToService(); game.ScoreToReceiver(); game.ScoreToReceiver(); game.ScoreToReceiver(); game.ScoreToReceiver(); //---------------Assert Precondition---------------- Assert.AreEqual("40-ADV", game.Score); //---------------Execute Test ---------------------- game.ScoreToReceiver(); //---------------Test Result ----------------------- Assert.AreEqual("40-GAME", game.Score); } [Test] public void ScoreToReceiver_When_DEUCE_ShouldSetScore_40_ADV() { //---------------Set up test pack------------------- var game = new Game(); game.ScoreToService(); game.ScoreToService(); game.ScoreToService(); game.ScoreToReceiver(); game.ScoreToReceiver(); game.ScoreToReceiver(); //---------------Assert Precondition---------------- Assert.AreEqual("DEUCE", game.Score); //---------------Execute Test ---------------------- game.ScoreToReceiver(); //---------------Test Result ----------------------- Assert.AreEqual("40-ADV", game.Score); } }
[TestFixture] public class TestPoint { // ReSharper disable InconsistentNaming [Test] public void NewPoint_ShouldSetToString_0() { //---------------Set up test pack------------------- //---------------Assert Precondition---------------- //---------------Execute Test ---------------------- var point = new Point(); //---------------Test Result ----------------------- Assert.IsNotNull(point); Assert.AreEqual(Point.LOVE, point.ToString()); } [Test] public void Score_When_0_ShouldSetToString_15() { //---------------Set up test pack------------------- var point = new Point(); //---------------Assert Precondition---------------- Assert.AreEqual(Point.LOVE, point.ToString(), "PRE CONDITION"); //---------------Execute Test ---------------------- point.Score(new Point()); //---------------Test Result ----------------------- Assert.AreEqual(Point.FIFTEEN, point.ToString()); } [Test] public void Score_When_15_ShouldSetToString_30() { //---------------Set up test pack------------------- var point = new Point(); point.Score(new Point()); //---------------Assert Precondition---------------- Assert.AreEqual(Point.FIFTEEN, point.ToString(), "PRE CONDITION"); //---------------Execute Test ---------------------- point.Score(new Point()); //---------------Test Result ----------------------- Assert.AreEqual(Point.THIRTY, point.ToString()); } [Test] public void Score_When_30_ShouldSetToString_40() { //---------------Set up test pack------------------- var point = new Point(); point.Score(new Point()); point.Score(new Point()); //---------------Assert Precondition---------------- Assert.AreEqual(Point.THIRTY, point.ToString(), "PRE CONDITION"); //---------------Execute Test ---------------------- point.Score(new Point()); //---------------Test Result ----------------------- Assert.AreEqual(Point.FORTY, point.ToString()); } [Test] public void Score_When_40_ShouldSetToString_GAME() { //---------------Set up test pack------------------- var point = new Point(); point.Score(new Point()); point.Score(new Point()); point.Score(new Point()); //---------------Assert Precondition---------------- Assert.AreEqual(Point.FORTY, point.ToString(), "PRE CONDITION"); //---------------Execute Test ---------------------- point.Score(new Point()); //---------------Test Result ----------------------- Assert.AreEqual(Point.GAME, point.ToString()); } [Test] public void Score_When_40_40_ShouldSetToString_ADV() { //---------------Set up test pack------------------- var point = new Point(); var opponentPoint = new Point(); point.Score(opponentPoint); point.Score(opponentPoint); point.Score(opponentPoint); opponentPoint.Score(point); opponentPoint.Score(point); opponentPoint.Score(point); //---------------Assert Precondition---------------- Assert.AreEqual(Point.FORTY, point.ToString(), "PRE CONDITION"); Assert.AreEqual(Point.FORTY, opponentPoint.ToString(), "PRE CONDITION"); //---------------Execute Test ---------------------- point.Score(opponentPoint); //---------------Test Result ----------------------- Assert.AreEqual(Point.ADVANTAGE, point.ToString()); } [Test] public void Score_When_40_ADV_ShouldSetToString_40() { //---------------Set up test pack------------------- var point = new Point(); var opponentPoint = new Point(); point.Score(opponentPoint); point.Score(opponentPoint); point.Score(opponentPoint); opponentPoint.Score(point); opponentPoint.Score(point); opponentPoint.Score(point); opponentPoint.Score(point); //---------------Assert Precondition---------------- Assert.AreEqual(Point.FORTY, point.ToString(), "PRE CONDITION"); Assert.AreEqual(Point.ADVANTAGE, opponentPoint.ToString(), "PRE CONDITION"); //---------------Execute Test ---------------------- point.Score(opponentPoint); //---------------Test Result ----------------------- Assert.AreEqual(Point.FORTY, point.ToString()); } [Test] public void Score_When_ADV_40_ShouldSetToString_GAME() { //---------------Set up test pack------------------- var point = new Point(); var opponentPoint = new Point(); point.Score(opponentPoint); point.Score(opponentPoint); point.Score(opponentPoint); opponentPoint.Score(point); opponentPoint.Score(point); opponentPoint.Score(point); point.Score(opponentPoint); //---------------Assert Precondition---------------- Assert.AreEqual(Point.ADVANTAGE, point.ToString(), "PRE CONDITION"); Assert.AreEqual(Point.FORTY, opponentPoint.ToString(), "PRE CONDITION"); //---------------Execute Test ---------------------- point.Score(opponentPoint); //---------------Test Result ----------------------- Assert.AreEqual(Point.GAME, point.ToString()); } [Test] public void Score_When_GAME_0_ShouldError() { //---------------Set up test pack------------------- var point = new Point(); var opponentPoint = new Point(); point.Score(opponentPoint); point.Score(opponentPoint); point.Score(opponentPoint); point.Score(opponentPoint); //---------------Assert Precondition---------------- Assert.AreEqual(Point.GAME, point.ToString(), "PRE CONDITION"); //---------------Execute Test ---------------------- var ex = Assert.Throws(() => point.Score(opponentPoint)); //---------------Test Result ----------------------- StringAssert.Contains("Game already completed!", ex.Message); } }