Tutorial – BDD and Dependency Injection in .Net (3)

In part 2 of this tutorial, we moved the decision logic out of the Game class into the Decision Engine class to separate concerns. Now we introduce dependency injection.

In this part of the tutorial, we will use dependency injection (DI) to improve the design of the code base. Zby provides a useful definition of dependency injection: “Dependency injection means giving an object its instance variables instead of letting it create them”.

In our case, we will be giving the Game object an instance of Decision Engine instead of letting the Game object create it itself. We will do this via the Game’s constructor, however it could be done though a property or a method. These alternatives are known as constructor injection, property injection and method injection respectively.

This is the essence of the dependency injection pattern. Confusion tends to creep in when a dependency injection container is introduced. DI containers, such as unity or Castle Windsor, provide mechanisms to aid in implementing the dependency injection pattern. However, they are not required to implement the pattern. I recommend the use of DI containers when the benefit of using one outweighs the complexity that is introduced by using it.

For the sake of simplicity, I will be using the dependency injection pattern and will avoid dependency injection containers for the time being. Returning to the rock, paper scissors example, DI will provide two main benefits:

  • Flexibility – we will be able to provide different implementations of the Decision Engine without changing the Game class. This ‘pluggable architecture’ adheres to the open close principle. An example of this would be a decision engine that not only decides on a result, but also logs the results to a data store. I will return to this should time allow.
  • Testability – during testing, we will be able to pass a mock object to the Game object, thus allowing us to test the Game class in isolation of the Decision Engine. This will be demonstrated in the code below.

Continue reading

Tutorial – BDD and Dependency Injection in .Net (2)

In this post we concentrate on separating concerns. We will not cover dependency injection within this post, but we will set things up so that we can cover that topic in the future.

We continue where part 1 left off. The SpecFlow feature file looks as follows:

PlayRoundFeature.feature

Feature: Play a single round of Rock Paper Scissors
	As a player
	I want to play a round
	So that I can test my luck

Scenario: Computer chooses Rock and the player chooses Paper
	Given the computer makes a secret choice of Rock
	When I choose Paper
	Then the result should be "Player Wins!"

Scenario: Computer chooses Rock and the player chooses Scissors
	Given the computer makes a secret choice of Rock
	When I choose Scissors
	Then the result should be "Computer Wins!"

The step definition file has the following:

PlayRoundSteps.cs

namespace RockPaperScissorsTest.Specs.Steps
{
    [Binding]
    public class PlayRoundSteps
    {
        private const string GameKey = "Game";

        [Given(@"the computer makes a secret choice of rock")]
        public void GivenTheComputerMakesASecretChoiceOfRock()
        {
            var game = new Game();
            ScenarioContext.Current.Add(GameKey, game);
        }

        [When(@"I choose paper")]
        public void WhenIChoosePaper()
        {
            var game = ScenarioContext.Current.Get(GameKey);
            game.PlayerMove = "Paper";
        }

        [When(@"I choose scissors")]
        public void WhenIChooseScissors()
        {
            var game = ScenarioContext.Current.Get(GameKey);
            game.PlayerMove = "Scissors";
        }

        [Then(@"the result should be ""Player Wins!""")]
        public void ThenTheResultShouldBePlayerWins()
        {
            var game = ScenarioContext.Current.Get(GameKey);
            Assert.AreEqual("Player Wins!", game.Result());
        }

        [Then(@"the result should be ""Computer Wins!""")]
        public void ThenTheResultShouldBeComputerWins()
        {
            var game = ScenarioContext.Current.Get(GameKey);
            Assert.AreEqual("Computer Wins!", game.Result());
        }

    }
}

The unit tests look as follows:

GameTest.cs


        [TestMethod]
        public void ComputerRock_PlayerPaper_PlayerWins()
        {
            var game = new Game();
            game.PlayerMove = "Paper";
            Assert.AreEqual("Player Wins!", game.Result());
        }

        [TestMethod]
        public void ComputerRock_PlayerScissors_ComputerWins()
        {
            var game = new Game();
            game.PlayerMove = "Scissors";
            Assert.AreEqual("Computer Wins!", game.Result());
        }

With the implementation being as follows:

Game.cs

namespace RockPaperScissors
{
    public class Game
    {
        private string _playerMove;
        public string PlayerMove
        {
            private get
            {
                if (String.IsNullOrEmpty(_playerMove))
                    throw new ArgumentNullException("PlayerMove");
                return _playerMove;
            }
            set
            {
                _playerMove = value;
            }
        }

        public string Result()
        {
            return PlayerMove == "Paper" ? "Player Wins!" : "Computer Wins!";
        }
    }
}

Turning a critical eye onto the Game.cs class we see that it has become responsible for deciding the result of the game as well as the string being returned to the user interface. This class is mixing domain logic with UI concerns. Therefore there are two reasons we may need to change this class. This breaks the single responsibility design principle.

Continue reading