views:

597

answers:

10

I have worked with code which had NUnit test written. But, I have never worked with mocking frameworks. What are they? I understand dependency injection and how it helps to improve the testability. I mean all dependencies can be mocked while unit testing. But, then why do we need mocking frameworks? Can't we simply create mock objects and provide dependencies. Am I missing something here? Thanks.

+2  A: 

The only reason to use a mocking library is that it makes mocking easier.

Sure, you can do it all without the library, and that is fine if it's simple, but as soon as they start getting complicated, libraries are much easier.

Think of this in terms of sorting algorithms, sure anyone can write one, but why? If the code already exists and is simple to call... why not use it?

chills42
Some mocking frameworks go a bit beyond doing it all by hand, like mocking statics.
Chris Missal
+8  A: 

You can create mock objects by hand and use them during testing using Dependency Injection frameworks...but letting a mocking framework generate your mock objects for you saves time.

As always, if using the framework adds too much complexity to be useful then don't use it.

Justin Niessner
+1  A: 

You certainly can mock your dependencies manually, but with a framework it takes a lot of the tedious work away. Also the assertions usually available make it worth it to learn.

mxmissile
+8  A: 
  • It makes mocking easier
  • They usually allow you to express testable assertions that refer to the interaction between objects.

Here you have an example:

var extension = MockRepository
    .GenerateMock<IContextExtension<StandardContext>>();
  var ctx = new StandardContext();
  ctx.AddExtension(extension);
  extension.AssertWasCalled(
    e=>e.Attach(null), 
    o=>o.Constraints(Is.Equal(ctx)));

You can see that I explicitly test that the Attach method of the IContextExtension was called and that the input parameter was said context object. It would make my test fail if that did not happen.

flq
+3  A: 

Using a mocking framework can be a much more lightweight and simple solution to provide mocks than actually creating a mock object for every object you want to mock.

For example, mocking frameworks are especially useful to do things like verify that a call was made (or even how many times that call was made). Making your own mock objects to check behaviors like this (while mocking behavior is a topic in itself) is tedious, and yet another place for you to introduce a bug.

Check out Rhino Mocks for an example of how powerful a mocking framework can be.

manu08
+3  A: 

Sometimes when working with third-party libraries, or even working with some aspects of the .NET framework, it is extremely difficult to write tests for some situations - for example, an HttpContext, or a Sharepoint object. Creating mock objects for those can become very cumbersome, so mocking frameworks take care of the basics so we can spend our time focusing on what makes our applications unique.

Rex M
+1  A: 

Mock objects take the place of any large/complex/external objects your code needs access to in order to run.

They are beneficial for a few reasons:

  • Your tests are meant to run fast and easily. If your code depends on, say, a database connection then you would need to have a fully configured and populated database running in order to run your tests. This can get annoying, so you create a replace - a "mock" - of the database connection object that just simulates the database.

  • You can control exactly what output comes out of the Mock objects and can therefore use them as controllable data sources to your tests.

  • You can create the mock before you create the real object in order to refine its interface. This is useful in Test-driven Development.

Frank Krueger
A: 

Well mocking frameworks make my life much easier and less tedious so I can spend time on actually writing code. Take for instance Mockito (in the Java world)

 //mock creation
 List mockedList = mock(List.class);

 //using mock object
 mockedList.add("one");
 mockedList.clear();

 //verification
 verify(mockedList).add("one");
 verify(mockedList).clear();

 //stubbing using built-in anyInt() argument matcher
 when(mockedList.get(anyInt())).thenReturn("element");

 //stubbing using hamcrest (let's say isValid() returns your own hamcrest matcher):
 when(mockedList.contains(argThat(isValid()))).thenReturn("element");

 //following prints "element"
 System.out.println(mockedList.get(999));

Though this is a contrived example if you replace List.class with MyComplex.class then the value of having a mocking framework becomes evident. You could write your own or do without but why would you want to go that route.

non sequitor
A: 

I first grok'd why I needed a mocking framework when I compared writing test doubles by hand for a set of unit tests (each test needed slightly different behaviour so I was creating subclasses of a base fake type for each test) with using something like RhinoMocks or Moq to do the same work.

Simply put it was much faster to use a framework to generate all of the fake objects I needed rather than writing (and debugging) my own fakes by hand.

Hamish Smith
A: 

Mocking frameworks allow you to isolate units of code that you wish to test from that code's dependencies. They also allow you to simulate various behaviors of your code's dependencies in a test environment that might be difficult to setup or reproduce otherwise.

For example if I have a class A containing business rules and logic that I wish to test, but this class A depends on a data-access classes, other business classes, even u/i classes, etc., these other classes can be mocked to perform in a certain manner (or in no manner at all in the case of loose mock behavior) to test the logic within your class A based on every imaginable way that these other classes could conceivably behave in a production environment.

To give a deeper example, suppose that your class A invokes a method on a data access class such as

public bool IsOrderOnHold(int orderNumber) {}

then a mock of that data access class could be setup to return true every time or to return false every time, to test how your class A responds to such circumstances.

Dave Falkner