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

Advertisements

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

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

This tutorial focuses on Behaviour Driven Development, Dependency Injection and application design in general. The primary technologies being used will be SpecFlow and MS Test. While we are targeting the .Net platform the content is applicable to most object oriented languages.

A Brief Introduction to Behaviour Driven Development

Behaviour Driven Development (BDD) is an ‘outside in’ or ‘top down’ development approach. Development starts from the user interface downwards as opposed to starting with the database design.  When there is no user interface (as in the beginning of this tutorial) we work from the highest level possible.

BDD encourages thin slices of work. Where we break features down into very small ‘end-to-end’ pieces of work. This work is expressed in the form of examples. This is known as specification by example and we will see this in the tutorial.

In SpecFlow speak, each example is known as a scenario. We need to implement a number of scenarios before the feature is considered complete. We will flesh out the design as we implement each scenario.

The following diagram from The RSpec Book shows the BDD cycle:

BDD Cycle

As depicted, there are two levels of testing – high level system or integration tests and lower level unit testing. The high level tests often drive a user interface and may be referred to as automated acceptance tests.

Not only will we be following the BDD cycle, but we will only implement the code we need to make the existing tests pass – and no more. We will be very strict with this. This may seem tedious to some however this approach is good to practice. You can always fall back to this approach should you become stuck when writing production code.

Interestingly TDD was always meant to have multiple levels of testing. In Extreme Programming Explained, Kent Beck and Cynthia Andres have the following to say about architects: “Architects on an XP team look for and execute large-scale refactorings, write system-level tests that stress the architecture, and implement stories”. This is similar to what we are trying to achieve in BDD. In fact Dan North introduced the term BDD to help him explain TDD to developers. This is why I say that BDD is TDD done properly.

These days it is common to hear teams say they are doing “TDD but not BDD”. By this they sometimes mean that they are writing system tests and unit tets, but they are not using a “BDD testing framework” like Cucumber or FitNesse. There is nothing wrong with this approach. Sometimes “we do TDD but not BDD’ means that the team members are not writing system level integration tests. This is better than no tests at all, however it is not true TDD and they are missing a trick.

A Brief Introduction to Dependency Injection

James Shaw does a great job of explaining Dependency Injection (DI). He points out that “Dependency Injection means giving an object its instance variables”. The instance variables are typically reference types which provide a layer of abstraction. We can give an object it’s instance variables through a number of different ways namely constructor injection, property injection, method injection.

There are many reasons for using Dependency Injection. The most obvious reason is that it makes the code more testable. It makes it easy to use mock objects in place of the real dependencies during testing. Testability is not the only reason, when done properly code which uses dependency injection tends to support the SOLID design principles, most notably the Single responsibility principle and Open/closed principle. This will be shown in the tutorial.

Dependency Injection is a simple concept, the confusion seems arise when Dependency Injection containers enter the discussion. For this reason I will not use DI Containers for the first few parts of this tutorial. All I will say is that DI Containers may help when composing objects, however they are not required to implement the dependency injection pattern.

Continue reading