Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I read an article recently which said that mock objects are often misunderstood and misused. Are there any clear mocking anti-patterns which I can look out for?

share|improve this question
    
is the article you read this one? martinfowler.com/articles/mocksArentStubs.html –  keppla Jun 10 '11 at 10:10
    
no... can't remember the exact source but will post here if I do –  Alison Jun 13 '11 at 11:12
    
I was taken to task on stackoverflow for mocking the mongodb API. I was pointed to a blog post that claimed it's wrong to mock any class you yourself did not write. I actually disagree with this but the opinion is out there. –  Kevin Nov 7 '11 at 1:35
add comment

5 Answers

I hate to see simple concrete classes mocked away. For example take the following simple class which has no dependencies on anything else:

public class Person
{
    private readonly string _firstName;
    private readonly string _surname;

    public Person(string firstName, string surname)
    {
        if (String.IsNullOrEmpty(firstName))
        {
            throw new ArgumentException("Must have first name");
        }

        if (String.IsNullOrEmpty(surname))
        {
            throw new ArgumentException("Must have a surname");
        }

        _firstName = firstName;
        _surname = surname;
    }

    public string Name 
    {
        get
        {
            return _firstName + " " + _surname;
        }
    }
}

In any tests involving this class I'd much rather a real one was instantiated and used rather than some interface like 'IPerson' being pulled out, a mocked one used and expectations set on the . By using the real one your test is more realistic (you have the parameter checks in place and the real implementation of the 'Name' property). For a simple class like this you aren't making your tests slower, less deterministic or muddying the logic (you aren't likely to need to know that Name was called when testing some other class) - which are the usual reasons for mocking/stubbing.

As an extension to this I've also seen people write tests where the mock is set up with an expectation, then the mock is called directly in the test. Unsuprisingly the test will always pass...hmmmm...

share|improve this answer
    
Thankfully mocking frameworks that I've used have been able to mock concrete classes, so pulling out interfaces at inconvenient points is not an issue. –  Alison Jun 13 '11 at 11:13
4  
That doesn't change the issue - this sort of simple thing should generally not be mocked even if you're using something which relaxes technical constraints on what can be mocked (e.g. a mock framework like TypeMock or a dynamic language). –  FinnNk Jun 13 '11 at 12:27
    
My rule of thumb has always been to mock for behavior, not for data. –  nono Oct 15 '13 at 17:41
add comment

It might sound obvious, but: Don't use mock objects in production code! I've seen more than one example where production code depended on the characteristics of certain mock objects (MockHttpServletRequest from the Springframework for example).

share|improve this answer
14  
i hope you followed your holy duty and submitted the code to DailyWTF? –  keppla Jun 10 '11 at 10:17
1  
In my previous work we were expressly forbidden from submitting anything from our codebase to DWTF. –  quant_dev Jun 10 '11 at 15:25
9  
@quant_dev: The fact that they had such a policy implies scary things about their developers... –  John Fisher Jun 10 '11 at 17:31
1  
Not really. It was a startup which had to develop a codebase quickly to sell a product, and then started consolidating and refactoring it to pay off the technical debt, as the product matured and further development was hindered by the (lack of) initial design. Managers knew the old codebase was shit, and invested time and resources into refactoring, but didn't want to risk any adverse publicity. –  quant_dev Jun 11 '11 at 11:03
    
Just taking shortcuts isn't really enough to get you only dailywtf... –  poolie Sep 12 '12 at 7:18
add comment

In my opinion it's the excessive method invocation check on mocks. I feel that this is a practice enforced by a few mocking frameworks like EasyMock, where the default mock behavior is to fail whenever there is an additional method invocation that what wasn't exactly specified before. This kind of strict mock method checking can lead to brittle designs where the tiniest change to the code can lead to a whole suite of tests failing, even though the core functionality is still the same.

A solution to this is starting to use stubs instead of mocks. An article I've found particularly enlightening about the subject was one found in Mockito's Javadoc: http://docs.mockito.googlecode.com/hg/org/mockito/Mockito.html (see "2. How about some stubbing?"), linking to: http://monkeyisland.pl/2008/07/12/should-i-worry-about-the-unexpected/.

I've enjoyed working with Mockito so far because it does not enforce this strict mocking behavior but the use of stubs instead. It also enforces method checking on specific ones instead of the whole mock object; so you end up checking only methods that really matter in your test scenario.

There are a few books here and there I can recommend that touch this subject and mocking and general:

xUnit Patterns

The Art of Unit Testing: With Examples in .Net

Next Generation Java Testing: TestNG and Advanced Concepts (this book is mostly about testNG but there's a nice chapter about mocking)

share|improve this answer
    
+1 for the point on excessive method invocation checks. However, there is always the flip side of the coin where an unexpected method invocation causes a failure in your method. Thankfully Mockito has the Answer.RETURNS_SMART_NULLS setting for mocks which helps diagnose this. –  Bringer128 Nov 7 '11 at 2:15
add comment

I have observed few anti-patterns in my experience.

  • Domain classes being mocked/stubbed where a state change may occur and that needs to be verified.
  • Integration tests interacting with a mix of mocks and concrete classes which defeats the purpose of integration tests.
  • Inadvertent use of mocks in production code (This should never happen)

Otherwise my experience with mocks especially Mockito has been a breeze. They have made tests very easy to write and maintain. GWT view/presenter interaction testing is much more easy with mocks than the GWTTestCase.

share|improve this answer
    
2 & 3 are definite problems! Have you got a simple example of (1)? –  Alison Jun 13 '11 at 11:15
add comment

I find that tests which utilise mocks across multiple layers of an application particularly difficult to decipher and change. However I think this has been mitigated in recent years by improved mock framework API's (I use JMock where convenient).

5 or 6 years ago API's like EasyMock were powerful but very cumbersome. Often the test code that made use of it was orders of magnitude more complicated than code it was testing. Back then I tried to influence teams I was in to use it very sparingly and make do with simple handcrafted mocks that were simply alternate implementations of interfaces specifically for testing.

Recently my strong opinions on this have become softer as the mocking API's have made tests that utilise them more readable. Essentially I want my code (including tests) to be changeable by other developers without making them feel like they're sifting through a mire of obscure API calls.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.