Advnace Mocking Scenarios With Active Record (using Rhino Mocks)

time to read 58 min | 11551 words

My recent post sparked some discussion in the Castle Mailing List, with some question of how to handle more complex scenarios. I managed to code those without much problem, as you can see below, but a few words first.

This method essentially mocks NHibernate for Active Record. This means that you have to understand what is happening (which is not a bad idea). I'm intimately familiar with both Active Record and NHibernate, and I had to look at the source to see what was happening.  If you intend to use this method, I highly recommend that you'll not put the expectations in the test itself, but move the expectation building to the MockScope, so you will be able to do something like:

mockedScope.OnFind(typeof(Blog),30).Return(mockedBlog);

Update: Added examples for both 2.0 and 1.1

Here are the examples (.Net 2.0):

[TestFixture]

public class Usage

{

    MockRepository mocks;

    ISession session;

 

    [TestFixtureSetUp]

    public void Initialize()

    {

        IConfigurationSource source = System.Configuration.ConfigurationManager.GetSection("activerecord") as IConfigurationSource; //this for .net 2.0

 

        ActiveRecordStarter.Initialize(typeof(Blog).Assembly, source);

    }

 

    [SetUp]

    public void SetUp()

    {

        mocks = new MockRepository();

        session = mocks.CreateMock<ISession>();

    }

 

    [TearDown]

    public void TearDown()

    {

        mocks.VerifyAll();

    }

 

    [Test]

    public void UsingMockedScope()

    {

        Blog mockedBlog = new Blog();

        Expect.Call(session.Load(typeof(Blog), 30)).Return(mockedBlog); ;

        mocks.ReplayAll();

        using (new MockScope(session))

        {

            Blog blogFromDatabase = Blog.Find(30);

            Assert.AreSame(mockedBlog, blogFromDatabase);

        }

    }

 

    [Test]

    public void UsingMockedScope_WithFindAll()

    {

        Blog mockedBlog = new Blog();

        IList returnedList = new ArrayList();

        returnedList.Add(mockedBlog);

        ICriteria criteria = mocks.CreateMock<ICriteria>();

        Expect.Call(session.CreateCriteria(typeof(Blog))).Return(criteria);

        Expect.Call(criteria.List()).Return(returnedList);

 

        mocks.ReplayAll();

 

        using (new MockScope(session))

        {

            Blog[] blogs = Blog.FindAll();

            Assert.AreEqual(1, blogs.Length);

            Assert.AreSame(mockedBlog, blogs[0]);

        }

    }

 

    [Test]

    public void UsingMockedScope_WithFindByProperty()

    {

        Blog mockedBlog = new Blog();

        IList returnedList = new ArrayList();

        returnedList.Add(mockedBlog);

 

        ICriteria criteria = mocks.CreateMock<ICriteria>();

        Expect.Call(session.CreateCriteria(typeof(Blog))).Return(criteria);

        Expect.Call(criteria.Add(null)).Constraints(

                Property.Value("Value", "Ayende @ Blog") & Property.Value("PropertyName", "Name")

            ).Return(criteria);

        Expect.Call(criteria.List()).Return(returnedList);

 

 

        mocks.ReplayAll();

 

        using (new MockScope(session))

        {

            Blog[] blogs = Blog.FindAllByProperty("Name", "Ayende @ Blog");

            Assert.AreEqual(1, blogs.Length);

            Assert.AreSame(mockedBlog, blogs[0]);

        }

    }

 

    [Test]

    public void UsingMockedScope_WithSimpleQuery()

    {

        Blog mockedBlog = new Blog();

        IList returnedList = new ArrayList();

        returnedList.Add(mockedBlog);

 

        IQuery query = mocks.CreateMock<IQuery>();

        Expect.Call(session.CreateQuery("from Blog b where b.Name = ?")).Return(query);

        Expect.Call(query.SetParameter(0, "Ayende @ Blog")).Return(query);

        Expect.Call(query.List()).Return(returnedList);

 

        mocks.ReplayAll();

 

        using (new MockScope(session))

        {

            SimpleQuery<Blog> q = new SimpleQuery<Blog>("from Blog b where b.Name = ?", "Ayende @ Blog");

            Blog[] blogs = q.Execute();

            Assert.AreEqual(1, blogs.Length);

            Assert.AreSame(mockedBlog, blogs[0]);

        }

    }

}

And here are the examples for .Net 1.1:

[TestFixture]

public class Usage

{

    MockRepository mocks;

    ISession session;

 

    [TestFixtureSetUp]

    public void Initialize()

    {

        IConfigurationSource source = System.Configuration.ConfigurationManager.GetSection("activerecord") as IConfigurationSource; //this for .net 2.0

 

        ActiveRecordStarter.Initialize(typeof(Blog).Assembly, source);

    }

 

    [SetUp]

    public void SetUp()

    {

        mocks = new MockRepository();

        session = (ISession)mocks.CreateMock(typeof(ISession));

    }

 

    [TearDown]

    public void TearDown()

    {

        mocks.VerifyAll();

    }

 

    [Test]

    public void UsingMockedScope()

    {

        Blog mockedBlog = new Blog();

        Expect.Call(session.Load(typeof(Blog), 30)).Return(mockedBlog); ;

        mocks.ReplayAll();

        using (new MockScope(session))

        {

            Blog blogFromDatabase = Blog.Find(30);

            Assert.AreSame(mockedBlog, blogFromDatabase);

        }

    }

 

    [Test]

    public void UsingMockedScope_WithFindAll()

    {

        Blog mockedBlog = new Blog();

        IList returnedList = new ArrayList();

        returnedList.Add(mockedBlog);

        ICriteria criteria = (ICriteria)mocks.CreateMock(typeof(ICriteria));

        Expect.Call(session.CreateCriteria(typeof(Blog))).Return(criteria);

        Expect.Call(criteria.List()).Return(returnedList);

 

        mocks.ReplayAll();

 

        using (new MockScope(session))

        {

            Blog[] blogs = Blog.FindAll();

            Assert.AreEqual(1, blogs.Length);

            Assert.AreSame(mockedBlog, blogs[0]);

        }

    }

 

    [Test]

    public void UsingMockedScope_WithFindByProperty()

    {

        Blog mockedBlog = new Blog();

        IList returnedList = new ArrayList();

        returnedList.Add(mockedBlog);

 

        ICriteria criteria = (ICriteria) mocks.CreateMock(typeof(ICriteria));

        Expect.Call(session.CreateCriteria(typeof(Blog))).Return(criteria);

        Expect.Call(criteria.Add(null)).Constraints(

                Property.Value("Value", "Ayende @ Blog") & Property.Value("PropertyName", "Name")

            ).Return(criteria);

        Expect.Call(criteria.List()).Return(returnedList);

 

 

        mocks.ReplayAll();

 

        using (new MockScope(session))

        {

            Blog[] blogs = Blog.FindAllByProperty("Name", "Ayende @ Blog");

            Assert.AreEqual(1, blogs.Length);

            Assert.AreSame(mockedBlog, blogs[0]);

        }

    }

 

    [Test]

    public void UsingMockedScope_WithSimpleQuery()

    {

        Blog mockedBlog = new Blog();

        IList returnedList = new ArrayList();

        returnedList.Add(mockedBlog);

 

        IQuery query = (IQuery)mocks.CreateMock(typeof(IQuery));

        Expect.Call(session.CreateQuery("from Blog b where b.Name = ?")).Return(query);

        Expect.Call(query.SetParameter(0, "Ayende @ Blog")).Return(query);

        Expect.Call(query.List()).Return(returnedList);

 

        mocks.ReplayAll();

 

        using (new MockScope(session))

        {

            IActiveRecordQuery q = new SimpleQuery(typeof(Blog),"from Blog b where b.Name = ?", "Ayende @ Blog");

            Blog[] blogs = (Blog[])q.Execute(session);

            Assert.AreEqual(1, blogs.Length);

            Assert.AreSame(mockedBlog, blogs[0]);

        }

    }

}