views:

458

answers:

7

What is the purpose of mocking?

I have been following some ASP.NET MVC tutorials that use NUnit for testing and Moq for mocking. I am a little unclear about the mocking part of it though.

+3  A: 

I'm new to mocking as well but I'll take a stab at this. In my experience mocking has two main benefits:

  • You can start working with objects before actually writing the implementation. You can define an interface and use mocking to work with the interface in unit tests or even code.
  • Mocking allows you to isolate the object under test in unit tests. With mock objects, you can completely control any objects that the object under test interacts with, therefore removing external dependencies from the test.
Jamie Ide
+6  A: 

Mocking allows you to isolate your class under test from its dependencies. Generally, you create a mock for each dependency for the class under test and set up the mock to return expected values. You then provide the mock to your class under test instead of a real copy of the class that your class under test is dependent on. You can then use the mocking framework to check that the expected calls were made to the mock object(s) to ensure that your class under test is operating correctly.

tvanfosson
+11  A: 

The purpose of mocking is to isolate the class being tested from other classes.

This is helpful when a class :

  • connects to an external resource (FileSystem, DB, network ... )
  • is expensive to setup, or not yet available (hardware being developed)
  • slows down the execution of the unit tests
  • has a non-deterministic behavior
  • has (or is) a user interface

It also makes it easier to test for error conditions, as your build your mock object so that it returns and error, throw an exception ...

The mock can record how it was invoked (function calls order, parameters) and this can be verified by the test. EDIT: For instance: The method you're testing sends a message, such as an IPC. The method of the mock object can record how many times it was invoked, the parameter he received (i.e. the message to be sent). Then the test can interrogate the mock object and assert on the number of messages sent, the content of the message ... Likewise, the mock object can record the methods that are called in a log string and the test can retrieve that string and assert on it.

Do not abuse of mock objects: test the behaviour rather than the implementation, or the unit tests will be too tightly coupled to the code, and brittle (break at refactoring).

Mock can be coded manually, or generated by a mocking framework.

philippe
Philippe, Thanks for the great answer. I am interested in the last sentence: 'The mock can record how it was invoked (function calls order, parameters) and this can be verified by the test.' This is new to me as I am new to unit-testing/mocking. What would be an example of this? It sounds useful.
theringostarrs
OK, will elaborate on this.
philippe
+3  A: 

"Mock" is a heavily overloaded term in testing & TDD circles. See Martin Fowler's article Mocks Aren't Stubs. A "proper" mock knows what values it's supposed to receive and lets you know when it doesn't get what was intended; this allows you to do interaction testing instead of state testing - you verify that the class under test is passing the correct messages to its collaborators, in the correct sequence. Interaction testing is quite different from conventional state testing and can be hard to get your head around. Keeping in mind that interaction testing is the point of mocks may make them easier to understand.

Carl Manaster
Fully disagree with the last line. Interaction testing is a side effect of mocking frameworks. Mocks have been hand-rolled for a long time for the sole purpose of state testing without relying on real resources.
womp
This is why I mentioned Mocks Aren't Stubs. If all you're doing with the mocking framework is state-testing (which is a perfectly valid use for mocking frameworks), you're using stubs, not (in the more formal sense) mocks.
Carl Manaster
Fully disagree with womp. I'm an author on the original mock paper, and that's not what we meant. Mocks were developed as a useful tool to help us think about how objects communicate.
Steve Freeman
+3  A: 

Its designed to poke fun at an individual instance from a group collection. Used a lot at irregular object gatherings.

I knew the Mother Grundys wouldn't cope. But "Resitance is futile" for me when it come to this question
I was going to say something similar :)
Jeff Davis
Well please do. We can gang up against the collective. We can have our own, what was it "Uni-matrix 00 or 01". Cheers.
It helps us insecure people feel better about ourselves by pointing out the utter stupidity of others. It may be a little pathetic to admit you partake in it, but it is also a heckuva lot of fun.
Charlie Flowers
+3  A: 

While mocking is usually understood as allowing for isolation of a class under test this isn't the main point of a mock (stubs are better for this). Instead we need to look at what happens when an object is told to do something which is one of 3 things..

  1. Direct Output - result of a method call
  2. Internal Changes - changes to the class during a method call
  3. Indirect Output - code under test calls a different class

State based testing is all about #1 and #2. #1 via looking at the result that the method gives you. #2 by accessing the objects internal state.

This leaves us with #3 for which there are two avenues we can take. The first is a by using a Mock and the second by using a Test Spy. The main difference is that on a Mock you create the expectations before executing the code under test and then have the mock verify them after, whereas with a Test Spy you execute the code under test and then ask the Test Spy if certain actions occurred.

So to sum all that up.. when you think about testing what a class does if you need to test indirect output (aka a call to another class) that is where Mocking comes into play.

ShaneC
A: 

One other answer :

  • Stub = fake objects to be able to run your test without the entire real context

  • Mock = fake object to record the interaction of your component and verify theses interactions

You can have several stubs in one test but only one mock because if you have more than one mock you certainly test more than one feature (and it defeat the purpose of the test one thing principle).

To go beyond the basics, Mocks are more behavioral verification than the traditionnal state verification of the test where you check the state of your component after acting on it (Arrange,Act, Assert with Mocks it is more Arrange, Act, Verify) :

State verification Assert.AreEqual(valueExpected,mycomponent.Property); Behavioral verification : myMock.WasCalled(MyMethod);

Matthieu