Monday, December 6, 2010

Mocking a View for Unit Testing

Had a very interesting question yesterday asking if it was possible to mock up a database view along side the in-memory SQLLite database we use for ActiveRecord.  Initially I figured it was a simple matter of just finding some form of attribute within the ActiveRecord class definition but it turns out that this is not the case.  Views not not actually supported by the CreateSchema() method we normally use with NHibernate/ActiveRecord.

As a work around you can create a view using the existing connection, for example I want to create a view called “mockview” which is based on the applications table.  All we need to do this is create a method:

private void CreateMockView()
{
    using (IDbCommand command = service.GetConnection().CreateCommand())
    {
        command.CommandText = "Create view mockview as select applicationid from applications";
        command.ExecuteNonQuery();
    }
}

If there is already an ActiveRecord class definition for this you need to decorate the class with the Schema=”none” parameter which will prevent the creation of a table with the same name.

[Serializable , ActiveRecord("mockview ", DynamicUpdate = true, Lazy = false, Schema="none")]
public partial class ApplicationsDAO : ActiveRecordBase    {
………………………….
}

Now you can query this to your hearts content.

If we want to query this but there is no ActiveRecord table definition we can just use a normal datareader, for example;

[Test]
public void GetApplications_Test()
{
    IList<Application> results = Application.FindAll();      // the AR Class
    Assert.IsTrue(results.Count > 0, "Returned values");
    _log.InfoFormat("GetAll Complete returned {0} records", results.Count);

    using (IDbCommand command = service.GetConnection().CreateCommand())
    {
        command.CommandText = "select applicationid from applications";  // the View on the database
        IDataReader reader = command.ExecuteReader();
        Assert.IsTrue(reader["applicationid"].ToString() == “1”, "there should be records in the view!");
    }
}