Setting attributes of classes updated by a mocked classes in RhinoMocks

Setting values on classes hidden inside methods under test and acted on by Mocks, using RhinoMocks.
September 07 2010

A common data pattern in most business applications is the Repository pattern.   An interface for a generic repository usually looks like the following:

public interface IRepository<T> where T : DomainEntity
{
    IList<T> GetAll();
    T GetById(int id);
    void Commit(T entity);
    void Delete(T entity);
}

public abstract class DomainEntity
{
    public int? Id { get; set; }
    public bool IsNew 
    {
        get { return Id != null; }
    }
}

Typically your service layer would co-ordinate entities and the repository to perform the required functionality.  Logic concerning insertion of entities needs to test if the entity has been successfully insert by checking the IsNew property.  The test for which could look like

public class Person : DomainEntity
{
    public string Name { get; set; }
    public Date DateOfBirth { get; set; }
}

public class IPersonRepository : IRepository<Person>
{
}

public class PersonService
{
    private IPersoneRepository _repository;

    public PersonService(IPersonRepository repository)
    {
        _repository = repository
    }

    public bool InsertPerson(string name, DateOfBirth dateOfBirth)
    {
        var newPerson = new Person
                        {
                            Name = name,
                            DateOfBirth = dateOfBirth
                        };

        _repository.Commit(newPerson)
        return !newPerson.IsNew;
    }
}


[Test]
public void Repository_insert_sets_id_field()
{
    // Arrange
    IPersonRepository repo = MockRepository.GenerateStub<IPersonRepository>();
    PersonSerivce service = new PersonService(repo);
    // Act
    bool result = service.InsertPerson("Test Pilot", DateTime.Now.AddYears(-30));

    // Assert
    Assert.IsTrue(result);

}

 

This test will fail though because the mock repository will not create and assign a Id primary key.  We need to simulate the creation of the primary key in the commit to ensure the IsNew property on the entity returns false.  This is done using the Callback method on the mock.

[Test]
public void Repository_insert_sets_id_field()
{
    // Arrange
    IPersonRepository repo = MockRepository.GenerateStub<IPersonRepository>();
    PersonSerivce service = new PersonService(repo);
    repo.Expect(r => r.Commit(Arg<Person>.Is.NotNull)
        .Callback(new Delegate.Function<bool, Person>(
                        person => {
                                    person.Id = 1;
                                    return true;
                                  }
                    ));

    // Act
    bool result = service.InsertPerson("Test Pilot", DateTime.Now.AddYears(-30));

    // Assert
    Assert.IsTrue(result);

}

Post a comment

comments powered by Disqus