Testing local objects in a method using Fake objects

I recently had a scenario where I needed to test whether calls to dependant objects were working as expected in a void method (an integration test). To do this, I constructed what is known as a Fake object, subsequently injecting this object into the constructor of my class to be tested (similar to my previous mock blog post). In my example, my fake simply delegates to the same method on the main concrete implementation, but introduce a new property into which  the result is stored (so we can perform asserts against this).

The difference between a mock and a fake is that whereas a mock sets up what will be returned from dependant objects in the test code, the fake sets this up via a new implementation of the dependant object. A good description of fakes can be found here.

(Note that stubs are different to fakes, in that they simply return hardcoded values).

Example Code

public class Foo
{
    private IDataAccessLayer dal;

    public Foo()
    {
        this.dal = new ConcreteDal();
    }

    public Foo(IDataAccessLayer dataAccessLayer)
    {
        this.dal = dataAccessLayer;
    }

    public void Bar()
    {
        // Call database to get count of something
        var count = dal.DoSomethingImportant(“SpecificGroupOrSomething”);
    }
}

public interface IDataAccessLayer
{
    int DoSomethingImportant(string key);
}

public class ConcreteDal : IDataAccessLayer
{
    public int DoSomethingImportant(string key)
    {
        // e.g. Perform a call to the database and do something complicated – 99 is dummy value
        return 99;
    }
}

public class FakeDal : IDataAccessLayer
{
    private IDataAccessLayer mainDal;

    public int ResultOfSomethingImportant { get; set; }

    public FakeDal()
    {
        this.mainDal = new ConcreteDal();
    }

    public int DoSomethingImportant(string key)
    {
        // Fake implementation of something, or in this case –
        // call main implementation and capture result
        var result = this.mainDal.DoSomethingImportant(“TestKey”);
        this.ResultOfSomethingImportant = result;
        return result;
    }
}

[TestClass]
public class FooTests
{
    [TestMethod]
    public void TestMethod1()
    {
        var fakeDal = new FakeDal();

        var foo = new Foo(fakeDal);
        foo.Bar();

        Assert.AreEqual(99, fakeDal.ResultOfSomethingImportant);
     }
}

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>