Search

Categories

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Send mail to the author(s) E-mail

# Tuesday, 16 August 2011

Business owner must choose the first stories to be developed in the first iteration.

“A user should be able to add a new type of item to the application”

Features:

  • An item type entity and a persistence layer
  • An item type domain service that can provide a list of item types in the data store
  • A user interface to enable business users to list existing item types and create new ones

Inside out / outside in… we are doing the former ie starting with the Repository layer.

http://nbehave.codeplex.com/releases/view/68223

Code Snippet
public class when_working_with_the_item_type_repository : Specification {
    }

    public class and_saving_a_valid_item_type : when_working_with_the_item_type_repository {
        private int _result;
        private IItemTypeRepository _itemTypeRepository;
        private ItemType _testItemType;
        private int _itemTypeId;

        protected override void Because_of() {
            _result = _itemTypeRepository.Save(_testItemType);
        }
        
        protected override void Establish_context() {
            base.Establish_context();

            var randomNumberGenerator = new Random();
            _itemTypeId = randomNumberGenerator.Next(32000);

            // making a mock ISessionFactory
            // which just returns the random number
            // when an ItemType is passed in and saved
            var sessionFactory = new Mock<ISessionFactory>();
            var session = new Mock<ISession>();
            session.Setup(s => s.Save(_testItemType))
                            .Returns(_itemTypeId);

            sessionFactory.Setup(sf => sf.OpenSession())
                            .Returns(session.Object);

            // injecting in our mock sessionFactory
            _itemTypeRepository = new ItemTypeRepository(sessionFactory.Object);
        }

        [Test]
        public void then_a_valid_item_type_id_should_be_returned() {
            _result.ShouldEqual(_itemTypeId);
        }
    }
Specification inherits off SpecBase which is NBehave.Spec.Nunit.    So basically Nunit with BDD style sugar.

Using Moq to Mock out the ORM (Fluent NHibernate).

Code Snippet
public interface IItemTypeRepository {
        int Save(ItemType _testItemType);
    }

    public class ItemTypeRepository : IItemTypeRepository {
        private ISessionFactory _sessionFactory;

        public ItemTypeRepository(ISessionFactory sessionFactory) {
            _sessionFactory = sessionFactory;
        }

        public int Save(ItemType itemType) {
            int id;
            using (var session = _sessionFactory.OpenSession()) {
                id = (int)session.Save(itemType);
                session.Flush();
            }
            return id;
        }
    }

Second test and Refactoring

Code Snippet
public class when_working_with_the_item_type_repository : Specification {
        protected IItemTypeRepository _itemTypeRepository;
        protected Mock<ISessionFactory> _sessionFactory;
        // protected so can restub in each test the required behaviour
        protected Mock<ISession> _session;

        protected override void Establish_context() {
            base.Establish_context();
            // Mock out FNH
            _sessionFactory = new Mock<ISessionFactory>();
            _session = new Mock<ISession>();

            _sessionFactory.Setup(sf => sf.OpenSession())
                            .Returns(_session.Object);

            _itemTypeRepository = new ItemTypeRepository(_sessionFactory.Object);
        }
    }

    // second test
    public class and_saving_an_invalid_item_type : when_working_with_the_item_type_repository {
        private Exception _result;

        protected override void Because_of() {
            try {
                _itemTypeRepository.Save(null);
            }
            catch (Exception exception) {
                _result = exception;
            }
        }

        protected override void Establish_context() {
            base.Establish_context();
            // the mock knows that when a null is passed
            // instead of an ItemType then throw ArgumentNullException
            _session.Setup(s => s.Save(null))
                            .Throws(new ArgumentNullException());
        }

        [Test]
        public void then_an_argument_null_exception_should_be_raised() {
            _result.ShouldBeInstanceOfType(typeof(ArgumentNullException));
        }
    }

    // first test
    public class and_saving_a_valid_item_type : when_working_with_the_item_type_repository {
        private int _result;
        private ItemType _testItemType;
        private int _itemTypeId;

        protected override void Because_of() {
            _result = _itemTypeRepository.Save(_testItemType);
        }
        
        protected override void Establish_context() {
            base.Establish_context();

            var randomNumberGenerator = new Random();
            _itemTypeId = randomNumberGenerator.Next(32000);

            // when passed an ItemType, return the random number
            _session.Setup(s => s.Save(_testItemType))
                            .Returns(_itemTypeId);
        }

        [Test]
        public void then_a_valid_item_type_id_should_be_returned() {
            _result.ShouldEqual(_itemTypeId);
        }
    }

Now have 2 unit tests.. which are testing the repository

  • Saving a valid item type returns newly created id
  • Saving an invalid item type throws an ArgumentNullException

The repository is being tested using Mocks of the FNH Save method.  Because we’re using FNH’s interfaces it should just work (after putting in config files and creating the DB!).

| | #