I am working on writing some unit tests with Rhino Mocks for a WPF application written in C# that uses Unity for dependency injection and uses MVVM achitechture. I'm not very experienced with unit testing with Rhino Mocks so I'm not sure what the best practices are yet.
In the view model I'm going to be writing unit tests for, there is a dependency injected data access class, we'll call it DataAccess, that is from an external assembly that I don't control. Only a single instance is registered with the Unity container because DataAccess has a cache, and it's desirable to share that instance across the whole application via the Unity container in order to improve performance. Now I need to mock DataAccess in my unit test obviously because I don't have control over the data in the database. I want to stub or expect the Retrieve method to return a specific value, but DataAccess doesn't implement an interface and the method I need to stub is not virtual. From what I've read online, Rhino Mocks can't override a non-virtual method, and the only other option is to mock an interface with the methods you want to override. Neither of those options are valid for this case because I don't own the DataAccess code. I've heard that TypeMock has the ability to override non-virtual methods but convincing my company to switch to a paid mocking library is probably not going to happen so I'm stuck with Rhino Mocks. So is there a way to mock this class and override this method with Rhino Mocks?
public class DataAccess //in an external assembly
{
public TEntity Retrieve(TKey key);
}
public class ViewModel //in the client project
{
[Dependency]
public DataAccess DataAccess { get; set; }
}
I came up with a possible solution but it doesn't use mocks and I'd like to use mocks because there are many places where we have this situation. My idea is to create a wrapper class (fake) for DataAccess that has the same methods and properties as DataAccess except all of the important methods/properties are marked virtual, and I'll put that class in my test project. Then in the unit test initializer I will register a type mapping from DataAccess to the wrapper class in my Unity container so that the VM instantiated in my unit test will get an instance of the wrapper class instead. Do you see any drawbacks to going in this direction aside from creating a bunch of wrapper classes?
public class DataAccessFake : DataAccess //in the test project
{
public new virtual TEntity Retrieve(TKey key) //hides the DataAccess Retrieve with a virtual one
{
return base.Retrieve(key);
}
}
new
keyword indicates that the method hides its inherited member. So yes, it should call the fake method. – StarChar