views:

147

answers:

3

Would you guys say that the use of mocks is better than not using mocks? Is mocking used only in unit testing or could it be used directly in the original project as the real object and switch it after?

I've been reading here and there and the most attractive thing about mocking I found was the layer isolation.

+5  A: 

mocks are definitely useful in unit testing. When you want to test A that relies on B, in isolation, then you mock B (with expected input/output) to test A. You make sure you test B separately to make sure it is correct.

In dynamic languages, they aren't strictly necessary. But mocking frameworks can help you verify that the expectations you set on the mock are met.

You should never use a mock as a real implementation. That type of thing is the stuff of jokes. "We can just mock the entire application! Yaaaaay!" Thats what interfaces/equivalent are for...

hvgotcodes
The other handy thing with mocks - they're often a lot faster to set up than the real thing (especially if say, the real thing is DB-tied), making running tests much, much faster.
Amber
very true. good addition.
hvgotcodes
when you say i should never use a mock as a real implementation, you mean i should use a mock only outside the real thing i want to test, or just that i should never use a mock as the final product - which is a obviously not.say i have a real method in class A that should call a real method in class B, is fine to mock the class B in the real class A, or should i test it in a testclass and setup the real class A and the mocked class B
Arturo
@arturo you mock in the context of unit testing only.
hvgotcodes
+1! Although you could use mocks or fakes in development to allow you to demo or UI test your app when a web service or other dependency isn't done.
TrueWill
+5  A: 

Ultimately, it can be argued that it is "just another way to do it." Software was written for decades and continues to be written in the absence of mocking.

It is primarily a facility of unit testing.

Where mocking/stubs really shine is test-driven development. The problem one faces in the absence of mocking/stubbing is that the web of dependencies in an application is often such that you have to build almost the entire application before you can write tests, and even then you're testing larger sections of functionality, such that isolating bugs becomes more difficult.

Consider the following:

  • I want to create ClassA and write tests to verify its behaviour.
  • I start writing the test (test-first to drive out the design).
  • Oops, ClassA needs to get data from RepositoryM.
  • I'll implement RepositoryM so that I can test ClassA.
  • Oh, but first let's write tests for RepositoryM.
  • Darn, RepositoryM really needs ServiceX to populate its data.
  • I'll implement ServiceX so I can test and implement RepositoryM so I can test and implement ClassA

…and on and on.

Using mocks allows you to start writing tests without implementing anything. All you need are interfaces.

Using a mocking framework makes test construction much faster.

Mocking/stubbing has ancillary benefits -- one of which is enforcement of programming to abstractions instead of implementations.

Jay
Mocking shines when you want to isolate a class for test; you don't need TDD for mocking.
hvgotcodes
@hvgotcodes Of course; only a portion of my answer pertains to TDD, and in that portion I'm saying that mocking is pretty important to TDD precisely because it allows this isolation. I meant this to augment the information you provided.
Jay
+2  A: 

Would you guys say that the use of mocks is better than not using mocks?

Is driving a motorbike better than driving a car? It depends what you're trying to achieve :).

Why use mocks?

Mocks versus state-based testing: While I generally like state-based testing because it feels more solid/straight forward, it's often the case that using mocks is the only way to verify that a unit of code performs its role correctly. Why? Well, when designing with the tell, don't ask principle in mind, classes often do not expose enough data to verify your expectations, so the only way to verify it's working properly is to check its behaviour/interactions with other collaborators.

A good example is a class that sends emails when an order is finalised -- the class won't have a "number of emails sent" property or anything similar, so you need to check that the appropriate method call was made. Mocks set expectations on the interactions.

While you can test the interactions by hand-rolling your own test double classes that expose this data (e.g. create a type that implements the required interface, then push method call information into a list, then assert against the stored state), mocking frameworks speed up the process by allowing us to only fill in the bits we actually care about.

Should I use mocks in production code?

Is mocking used only in unit testing or could it be used directly in the original project as the real object and switch it after?

If by "mocking" you mean using a "a 'fake' type that can be swapped in and behave in a sensible manner", then yes -- I've often used 'fake' types such as an in memory dictionary to substitute for database connections and so forth. They can act as a useful stopgap in non-live production code.

Similarly, if you program to an interface, you can create a working skeleton of an application with stubbed out functionality. This helps get a full programming structure fleshed out without having to focus on details. You can substitute in the real implementation once it's available (though expect some integration errors if you're not backed by integration tests).

If, on the other hand, by "mocking" you mean "using a mocking framework in the production code", then no -- I wouldn't recommend doing that, I'd hand-write the fake implementations and stay free of the dependency, plus it'll be easier to reason about and debug.

Mark Simpson