Archive for the ‘mocks’ Category
Rationalising mocked dependencies using concrete types
This really is amazingly obvious and simple, but for some reason it never occurred to me.
The situation I’ve been getting myself into is that I have Business Logic actions that do a very discrete bit of logic, these will have dependencies on data access repositories as well as other business logic actions (potentially). I was happily using interfaces for the data access dependencies and then continued to use them for business logic dependencies, this lead to a bit of a mass of interfaces, and I also ended up with tests that mocked all these dependencies, resulting in missing lots of problems that occur in the interaction between business logic actions.
What I really want is that all data access dependencies can be replaced by mocks, but the ‘real’ instances of all the business logic actions are used. This seemed hard to achieve as we are not using an IOC container for our dependency injection (What a pain!) so use a default constructor for each class that just provides real implementations. So if we use a real instance of the business logic dependency we either have to know about it’s dependencies (resulting in massive constructors for all possible dependencies in the object graph).
The solution I hit upon today seems kind of obvious now (and of course is completely irrelevant if you have an IOC Container). Specify all data access dependcies by interface so they can be mocked out. Specify all business logic dependencies as concrete dependencies (still in the constructor). Use default constructors to use default instances of all the dependencies. In tests create all business logic objects for the required object graph using dependency injection, use mocks for data access dependencies and real instances for business logic actions.
public class Class1
{
private IDataAccess1 dataAccess1Dependency;
private Class2 class2Dependency;
public Class1()
: this(new DataAccess1(), new Class2())
{ }
public Class1(IDataAccess1 dataAccess1, Class2 class2)
{
this.dataAccess1Dependency = dataAccess1;
this.class2Dependency = class2;
}
public int MethodToTest()
{
return class2Dependency.Method() + dataAccess1Dependency.GetInt();
}
}
|
public class Class2
{
private IDataAccess2 dataAccess2Dependency;
public Class2()
: this(new DataAccess2())
{ }
public Class2(IDataAccess2 dataAccess2)
{
this.dataAccess2Dependency = dataAccess2;
}
public int Method()
{
return dataAccess2Dependency.GetInt();
}
}
|
/// <summary>
///A test for MethodToTest
///</summary>
[TestMethod()]
public void MethodToTestTest()
{
MockRepository mocks = new MockRepository();
IDataAccess1 mockDA1 = mocks.DynamicMock<IDataAccess1>();
IDataAccess2 mockDA2 = mocks.DynamicMock<IDataAccess2>();
Class2 class2Instance = new Class2(mockDA2);
Class1 target = new Class1(mockDA1, class2Instance);
using (mocks.Record())
{
Expect.Call(mockDA1.GetInt()).Return(5);
Expect.Call(mockDA2.GetInt()).Return(6);
}
using (mocks.Playback())
{
int expected = 11;//5+6
int actual = target.MethodToTest();
Assert.AreEqual(expected, actual);
}
}
|
Strictly mocked operations rather than strictly mocked interfaces?
Recently I’ve been planning to contribute to the rhino mocks wiki. One of the topics I thought I would write about is when I would use the different types of mock (CreateMock, DynamicMock, Stub etc). To this end I was trying to think why you would want to use CreateMock; that is a mock that enforces strict replay semantics.
When would you want strict replay?
- When you don’t want your target (System Under Test) to make calls other than those that you have expressly defined. Usually I don’t think you care, but sometimes these calls will be ‘expensive’, in the sense that they do something like make a web service call, and so we don’t want to make the call un-necessarily. Or that they cause a change of state, that is where making the call would result in incorrect behaviour of the system (e.g. A method that called CreditCardService.TakePayment() twice instead of once would probably be a ‘bad thing’). In these examples what I am really bothered about is that certain mocked operations obey strict replay semantics, rather than the whole interface.
How to use strictly mocked operations in Rhino Mocks
So if we want a mocked operation that obeys strict replay semantics we can simply use a DynamicMock and set individual operations to be restricted using Repeat.Never() or Repeat.Times(), I would also argue that this will result in much more expressive tests as you are expressly saying what operations should not be called rather than hiding this in the type of mock created.
I am not saying that a strictly mocked interface is completely un-necessary, sometimes you know that an interface is full of methods we don’t want to call (such as a web service client), and we don’t want to have to enumerate every method. Rather you should probably think about what you want to restrict calls to.
Suggested rule of thumb:
- If the interface is to an ‘expensive’ class to call use a strictly mocked interface.
- If the interface contains methods which result in a change of state then certain methods should be strictly mocked.
Using Rhino Mocks to test private methods on an abstract class
Firstly it is arguable that you should not be trying to directly test a private method on an abstract class, as tests should focus on the public methods, it should be upto the class where it uses private methods. However, if you do want to do this there is a way. In my case I was trying to use Test Driven Development to modify an existing code base without unit tests. Rather than retro-fit them to the rest of the code I wanted to minimise the code I was testing by directly testing a private method (which happened to be on an abstract class).
The method I chose used two sub-methods, one for testing abstract classes and one for testing private methods, and they actually fitted together really easily.
- Use Rhino Mocks test the abstract class – Rhino Mocks allows for testing of abstract classes using the ‘partial mock‘ concept.
- Use visual studio private accessors to access the private methods – If you have a version of Visual Studio that supports MS Test you can simply right click on a private method and choose ‘Create Private Accessor’. The accessor that is created accepts an instance of the class as a constructor, so when you pass in the Partial Mock created previously you end up with a class exposing the private methods as public that can be directly called… awesum!
Should we use a mocking framework?
At the moment I’m tasked with investigating mocking frameworks. Currently we are using hand-written mocks/stubs, and I need to see what mocking frameworks are out there and what benefits they would bring. So far I’ve been focussing on Rhino Mocks and have looked briefly at TypeMock. Initial findings (based around Rhino Mocks) are:
Pros:
- Behaviour testing – our current mocks/stubs only allow for state testing so you can test the final result/state of the System Under Test (SUT) but you can’t verify any behaviour it performed. Where there is a requirement for the SUT to make a call to an external dependency (for example) we have no way of testing this
- Ordered behaviour testing – can specify the order that the SUT should perform certain actions, can nest different groupings of ordered and unordered behaviours.
- Event handling – although we have no immediate need for this as the code we are TDDing (is that a word?) does not use events, at some point we might use events, particularly for UI testing.
- No need to create the mock/stub – Created dynamically within the test, will save a significant amount of time
- Decoupling of tests – by not using a single hand coded mock we will avoid coupling tests together by sharing a single mock.
- Help encourage best practice – hand coded mocks are probably easier to get wrong than framework mocks.
- Rhino Mocks is free to use and is simply a dll.
- Can work side-by-side with other frameworks and/or hand written mocks.
- Mocking of classes – need to look more at this.
Cons:
- Require developers to learn how to use the framework. I would say that from scratch it would probably be easier to learn how to use Rhino Mocks than to learn how to use our hand written mocks.
- Rhino Mocks is currently developed by a single person (I believe) this may have an impact on the long term support of this tooling.
- Given enough time we could probably do most (everything) that a framework gives us, however why re-invent the wheel? Every new functionality we need from a hand written mock needs to be thought about – most of this thinking already done in the framework
Any comments or further points are welcomed!
Mocks Aren’t Stubs
I’ve just read a really interesting article by Martin Fowler ‘Mocks Aren’t Stubs‘. This lead me to the conclusion that I have also been confusing the terms mocks and stubs. To try and summarise the key difference between mocks and stubs is chiefly that of testing behaviour and/or state. Testing state means that you are only interested in the final outcome of the objects and their eventual state, and not all how they reached it; Testing behaviour means that you are instead interested in the behaviour of the objects and how they got to their final state. A stub will not, in general, support testing of behaviour, whereas a mock is fundamentally all about behaviour testing.
So in my previous post “Mocking without a mocking framework” I was really talking about stubbing. Specifically combining Dependency Injection with (dynamic?) stubbing to support testing.
I think a really interesting question is “do you want behaviour testing?” It seems unnatural for a test to care how an object came up with its answer.
Mocking without a mocking framework
I have not yet had the opportunity to use a proper mocking framework. My project has a future investigation into them, but it’s a low priority. However we are using Test Driven Development, so we have started using mocks (with dependency injection), so far the mocks have been statically defined and we are ‘learning as we go’ in the sense that the quality of the mock is changing as is our technique for creating them. We started off with a mock of a database with hard coded data in it, if you like we were replicating a simple set of data that the mock would interrogate. Over time this became very messy and was difficult to change for a specific test as you could break an existing test. The next approach was to remove all hard coded data and provide a mock that could be dynamically loaded with data by the test. This seems better (and more like how mocking frameworks work I believe). However recently I realised the method for loading data was flawed as if a class called the same method twice, but required different output on each call then the mock would not be able to provide this. The following shows my current thinking for how to define a bespoke mock with dynamically loaded data. Using a queue to load the data for each call.
- Create your mock implementing the mocked object(s) interface(s)
- Create a field/property of type queue<type> for each type of data that needs to be returned
- Create a constructor for the mock that news all the queues
- For each method on the interface(s) take the appropriate queue and Dequeue() an item from it
public class MockDB:ICustomerDataAccess
{
#region Dynamically loaded results
private Queue<List<Customer>> loadedCustomerListQueue;
public Queue<List<Customer>> LoadedCustomerListQueue
{
get { return loadedCustomerListQueue; }
set { loadedCustomerListQueue = value;}
}
private Queue<Customer> loadedCustomerQueue;
public Queue<Customer> LoadedCustomerQueue
{
get { return loadedCustomerQueue; }
set { loadedCustomerQueue = value; }
}
#endregion
public MockDB2()
{
LoadedCustomerListQueue = new Queue<List<Customer>>();
LoadedCustomerQueue = new Queue<Customer>();
}
#region ICustomerDataAccess Members
public List<Customer> GetCustomerByForeignKey(long ID)
{
return LoadedCustomerListQueue.Dequeue();
}
public Customer GetCustomerById(long id)
{
return LoadedCustomerQueue.Dequeue();
}
#endregion }
To use the mock in a test:
- Create an instance of the mock
- Enqueue items into the appropriate queue in the order that they should be returned in the tested class.
[TestMethod()]
[ExpectedException(typeof(CustomerMaintenanceException))]
public void UpdateCustomer_DoesntExist_Fail()
{
MockDB Mock= new MockDB();
UpdateCustomer target = new UpdateCustomer(Mock);
Customer NonExistant=new Customer();
Mock.LoadedCustomerQueue.Enqueue(null);
target.Execute(NonExistant);
}
Some points to note:
- You can enqueue null values onto a queue
- You can have a queue of lists
- This only works if the tested class has a predictable logic flow, but for a proper unit test this should always(?) be the case
- This is not meant to be better or even anywhere near as good as a mocking framework, but where you can’t use a framework this approach seems sensible
Update: As my knowledge of mocking has improved I have realised that this is not really mocking, rather a sort of dynamic stubbing (see this post)
How to handle dependency injection with nested dependencies
Recently I managed to get myself rather confused trying to use Test Driven Development to test a specific business logic class (Class A). Part of the business logic had been refactored into a seperate business logic class (Class B), this class had a set of dependencies that were properly coded to allow for dependency injection. The problem was that Class A also included all the dependencies of Class B, and when the class B was called the dependencies were setup based on the dependencies of Class A. This all seemed ‘ok’ until I decided that a unit test of Class A should not really test Class B. (This is obvious when you think about it, but because Class B had originally been part of Class A it hadn’t clicked straight away). Having never worked with dependency injection where there are nested dependencies I had a little trouble refactoring to allow class B to be mocked.
Following are the guidelines I reached for working with nested dependencies:
- The dependencies of Class B should not be included in the dependencies of Class A
- The operations in Class B need to be extracted into an interface (IClassB)
- Class B should implement interface IClassB
- Class A should operate on an instance of this interface
- A Mock of Class B is created that also implements IClassB
- When setting up Class A (e.g. from a unit test) the dependency on IClassB needs to be initialised using the MockClassB
If using default constructors to setup the ‘default’ dependencies (I believe this is known as “poor man’s dependency injection”) then the default constructor for Class A should simply create a default instance of ClassB (allowing Class B to setup its own default dependencies)
Leave a Comment
Leave a Comment
Leave a Comment