Archive for the ‘TDD’ Category
Translation Tester, Part 2 – Approach
In part 1 of this series I described the problem I’m trying to solve. Before I delve into solving the problem I’d like to take a quick moment to reflect on the development approach I plan to take for this project.
This is the first time I’ve tried to do any development outside of work, so I’m going to acknowledge from the outset that I don’t have a very detailed approach in mind, and I’m more than likely to change it as I go along. This fits quite well with my experience of agile development methodologies, so I’m going to try and put as many of the agile techniques into practice that I can. I’m pretty much development centric, so I’d also like to have a look at some of the related skills relating to requirements analyis and project management.
So as I see it the stages that I’ll need to go through in approximate order are:
- Initial requirements
- Iteration 0 – Get a skeleton solution with Continuous Integration etc
- High Level Design – I don’t want to get into too much detail at this stage, but just taking a moment to think of a broad design might help
- Find a suitable requirement/use case and implement it using Test Driven Development
- Analyse what comes out of the implementation and update requirements etc as needed. Lessons learned etc.
- Repeat steps 4 and 5 until all the requirements have been met.
So that’s my very rough approach, I’m sure I’ve missed oodles, so please drop a comment to suggest any pit-falls etc.
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.
TALC Driven Development
Recently I’ve been reading several blog posts about the effectiveness of Test Driven Development. Of particular interest is Jacob Proffit’s TDD or POUT
It seems to me that there is Plain Old Unit Testing, which I would argue implies “test at the end” unit testing at one of the spectrum, and then pure TDD at the other end. I see myself being near the TDD side, but not all the way; in fact I would categorise my approach as “Test After Little Code” Driven Development, or Pragmatic Unit Testing. What I tend to do is write a little bit of code first then write a test that exercises the code. From that point I’ll do one of two things, either write another little bit code and then test it, or sometimes write another test which deals with a slightly different case and then write the code to make it pass. Often different situations seem to lend themselves to a different approach.
I’m not sure exactly how Jacob does POUTing, but I’d imagine he doesn’t leave all the unit testing to the end. I think this is the real ‘enemy’ of unit testing, as by the end you are facing all the issues that TDD addresses such as code that isn’t testable, or no time left to test. These issues aren’t only solved by TDD, they can also be solved by incremental unit testing.
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)
How many tests should I write for a unit
When coding using Test Driven Development (TDD). It is sometimes tricky to figure out how many tests you should write. (Forgetting about the whole tests vs. asserts debate). I believe the guideline should be that the minimum amount of tests you should write is the number required to get 100% of the unit code covered. This means that every logic branch of the code is tested. From a requirements point of view this will equate to one test per possible type of successful outcome and one test per exception explicitly thrown in the code (failure outcomes). I am sure that this is not true in all cases, and it is really just a minimum.
Leave a Comment
Leave a Comment
Leave a Comment