Friday, September 28, 2012

Using Thoughtbot's factory_girl for Ruby in .net unit test setup methods


FactoryGirl is a fixtures replacement with a straightforward definition syntax, support for multiple build strategies (saved instances, unsaved instances, attribute hashes, and stubbed objects), and support for multiple factories for the same class including factory inheritance. James Kovacs has created a nice implementation of the FactoryGirl class in .NET. You can follow this link to check out his article on implementing the FactoryGirl in .NET. I have extended the FactoryGirl implementation by using Moq to register and invoke stubs to use in unit test methods.

public class FactoryGirlStubs
{

    private static readonly IDictionary<Type, object> stubs = new Dictionary<Type, object>();

    public static IEnumerable<Type> DefinedStubs
    {
        get { return stubs.Select(x => x.Key); }
    }

    public static void ClearStubDefinitions()
    {
        stubs.Clear();
    }

    public static void ClearStub()
    {
        stubs.Remove(typeof(T));
    }

    public static T BuildStub() where T : class
    {
        var result = (T)stubs[typeof(T)];
        return result;
    }

    public static void DefineStub() where T : class
    {
        var mock = new Mock();
        mock.SetupAllProperties();
        if (stubs.ContainsKey(typeof(T))) throw new DuplicateStubException();
        stubs.Add(typeof(T), mock.Object);
    }

    public static void DefineStub(Expression<Action> expression) where T : class
    {
        var mock = new Mock();
        mock.Setup(expression);
        mock.SetupAllProperties();
        if (stubs.ContainsKey(typeof(T))) throw new DuplicateStubException();
        stubs.Add(typeof(T), mock.Object);
    }

    public static void DefineStub(Expression<Func> expression, TResult result) where T : class
    {
        var mock = new Mock();
        mock.Setup(expression).Returns(result);
        mock.SetupAllProperties();
        if (stubs.ContainsKey(typeof(T))) throw new DuplicateStubException();
        stubs.Add(typeof(T), mock.Object);
    }
}

Test methods

[TestMethod]
public void DefineAddsTheStubsToTheStore()
{
    FactoryGirlStubs.DefineStub<ICustomerRepository>();
    Assert.IsTrue(FactoryGirlStubs.DefinedStubs.Any(x => x.Name.Contains("ICustomerRepository")));
    FactoryGirlStubs.ClearStubDefinitions();
}

[TestMethod]
public void BuildShouldReturnTheDefinedStubFromStore()
{
    FactoryGirlStubs.DefineStub<ICustomerRepository>();
    var repository = FactoryGirlStubs.BuildStub<ICustomerRepository>();
    Assert.IsInstanceOfType(repository, typeof(ICustomerRepository));
    FactoryGirlStubs.ClearStubDefinitions();
}
       
[TestMethod]
public void DefineWithSetupRegistrationsShouldReturnResultwhenSetupMethodIsInvoked()
{
    FactoryGirlStubs.DefineStub<ICustomerRepository, Customer>(x => x.GetById(1), new Customer { FirstName = "Prajeesh" });
    var repository = FactoryGirlStubs.BuildStub<ICustomerRepository>();
    Assert.IsTrue(repository.GetById(1).FirstName == "Prajeesh");
    FactoryGirlStubs.ClearStubDefinitions();
}

Saturday, September 22, 2012

Refactoring to Maybe pattern


The NullReferenceException is the most commonly occurring bugs in any programming language.
Passing nulls from a method leaves the responsibility to check the validity of the response object to the callee object/ method which leaves the space of null reference exceptions. For example in the code given below, the method which calls the repository’s GetById method needs to make sure that the Customer object is a valid one before making the assertions.
[TestMethod]
public void GetCustomerReturnsCustomerWithIDFromDB()
{
    var repository = new CustomerRepository(_dbContext);
    const int customerId = 5;
    var customer = repository.GetById(customerId);
    if(customer != null) Assert.AreEqual(customer.Id, 5);
    Assert.Inconclusive(string.Format("Customer with Id {0} was not found in the context", 5));
}
public Customer GetById(int id)
{
    return _context.Customers.FirstOrDefault(x => x.Id == id);
}
Refactoring the code to a maybe pattern implementation will make the repository define the contract of GetById to return a Maybe object which the callee always expects.
public interface Maybe<out T>
{
    bool HasValue { get; }
    T Value { get; }
}
public class Some : Maybe where T : class
{
    private T _value;

    public Some(T value)
    {
        _value = value;
    }

    public bool HasValue { get { return true; } }
    public T Value { get { return _value; } }
}
public class None : Maybe where T : class
{
    public bool HasValue { get { return false; } }
    public T Value { get { throw new MaybeException();} }
}
The GetById method signature now changes to
public Maybe<Customer> GetById(int id)
{
    var customer = _context.Customers.FirstOrDefault(x => x.Id == id);
    return customer == null ? new None<Customer>() : new Some<Customer>(customer) as Maybe<Customer>;
}

Sunday, September 9, 2012

Refactoring implicit language elements to form interpreters


In business applications, while creating searching algorithms you need to create a search context which consists of a combination of multiple algebraic expressions. A simple example is given below where the filter for searching books is created by combining multiple expressions as in the code sample below.

[TestMethod]
public void GetAllBooksInRangeByTopicShouldReturnAllBooksInThePriceRangeFilteredByTopic()
{
    var amazonService = new BookStore();
    const decimal fromRange = 50;
    const decimal toRange = 100;
    const string genre = "Travel Guide";
    var books = amazonService.GetBooksByPriceRangeAndGenre(fromRange, toRange, genre);
    Assert.IsTrue(books.Any());
}

public IEnumerable<Book> GetBooksByPriceRangeAndGenre(decimal from, decimal to, string genre)
{
    return GetAll().Where(x => x.Genre.Name.ToLower().Contains(genre.Trim().ToLower())
                                && (x.Price >= from && x.Price <= to));
}

We can refactor these expressions to a more readable and maintainable structure by creating specifications using the interpreter pattern as given below.


public IEnumerable<Book> GetBooksByPriceRangeAndGenre(decimal from, decimal to, string genre)
{
    var bookSpec = GetBookSpec(genre, from, to);
    return GetAll().Where(bookSpec.SatisfiedBy());
}

private BookSpecification GetBookSpec(string genre, decimal from, decimal to)
{
    return new BookSpecification(from, to, genre);
}

public class BookSpecification : ISpecification<Book>
{
    private readonly decimal _from;
    private readonly decimal _to;
    private readonly string _genre;

    public BookSpecification(decimal from, decimal to, string genre)
    {
        _from = from;
        _to = to;
        _genre = genre;
    }

    public Expression<Func<Book, bool>> SatisfiedBy()
    {
        return new GenreSpecification(_genre).AND(new PriceRangeSpecification(_from, _to)).SatisfiedBy();
    }
}

public class GenreSpecification : ISpecification<Book>
{
    private readonly string _genre;

    public GenreSpecification(string genre)
    {
        _genre = genre.Trim().ToLower();
    }
       
    public Expression<Func<Book, bool>> SatisfiedBy()
    {
        return new Specification<Book>(x => x.Genre.Name.ToLower().Contains(_genre)).SatisfiedBy();
    }
}

public class PriceRangeSpecification : ISpecification<Book>
{
    private readonly decimal _from;
    private readonly decimal _to;

    public PriceRangeSpecification(decimal from, decimal to)
    {
        _from = from;
        _to = to;
    }

    public Expression<Func<Book, bool>> SatisfiedBy()
    {
        return new Specification<Book>(x => x.Price >= _from && x.Price <= _to).SatisfiedBy();
    }
}