Mocking database integration with Simple.Data

I just discovered what might be a super-duper-happy-path to mocking database integration using the Simple.Data framework.
Mocking Db integration seems to be a constant source of frameworks and practices. And now I've got one myself.

Some context

The Simple.Data framework allready provides an XML mocking provider that allows you to define data in xml that later can used as a datasource.
Using this provider can be rather cumbersome as you have to define all your data up front in XML.
But:
Simple.Data is based the .Net 4 dynamic realm, and all return values are allways dynamic. This fact provides us the freedom to simply replace whatever Simple.Data returns, with our own mock data.
The only requirement is that the call to Database.Openxxx is abstracted into som kind of wrapper, as the starting poin in Simple.Data is a static factory class (Simple.Data.Database) and thus it cannot be intercepted.

Some code

Here is a small sample using FakeItEasy

dynamic dbResult = new ExpandoObject();
dbResult.TableName = new ExpandoObject():
dbResult.TableName.DbQueryMethod = new Func<Dynamic> ( ()=>
        {
                var result1 = new ExpandoObject();
                result1.Value1 = "value";
                IEnumerable<dynamic> result = new List<dynamic> { result1 };
                return result;
        }

var dbProvider = A.Fake<IDbProvider>();
A.CallTo(dbProvider).WithReturnType<dynamic>().Returns(dbResult);

var objectToBeTested = new SomeClass(dbProvider);

objectToBeTested.DoSomething();
Assert.Equals("value", objectToBeTeste.Value);

The someClass that is under test would be something like this:

public class SomeClass
{
    IDbProvider _dbProvider;
       
        public Value { get; private set; }
       
        public SomeClass(IDbProvider dbProvider)
        {
                _dbProvider = dbProvider;
        }
       
        public void DoSomething()
        {
                var result = _dbProvider.DbQueryMethod();
                Value = result.First().Value1;
        }
}

Going further

I just though of this now, and the Idea is still rather raw and not as elegant as it probably could be.
The next logical step would be to wrap the creation of the dbResult mock in a builder of some kind. A dynamic builder would make the most sense as it conforms with conventions from the rest of Simple.Data.

Som pseudo code describing a test using a dynamic builder:

dynamic dbResult = SimpleDataMock.ForTablename.DbQueryMethod().Returns(values);

var dbProvider = A.Fake<IDbProvider>();
A.CallTo(dbProvider).WithReturnType<dynamic>().Returns(dbResult);
var objectToBeTested = new SomeClass(dbProvider);

objectToBeTested.DoSomething();
Assert.Equals("value", objectToBeTeste.Value);

As allways I welcome any comments, suggestions and critique.

Update

I have now started writing out this idea in code.
The project can be found at github: https://github.com/Vidarls/Simple.Data.FakeResult
Still very much work in progress. but it works for basic stub needs.

Categories: