What is a mock and when should you use it?
Asked Answered
C

5

30

I just read the Wikipedia article on mock objects, but I'm still not entirely clear on their purpose. It appears they are objects that are created by a test framework when the actual object would be too complex or unpredictable (you know 100% sure what the values of the mock object are because you fully control them).

However, I was under the impression that all testing is done with objects of known values, so I must be missing something. For example, in a course project, we were tasked with a calendar application. Our test suite consisted of event objects that we knew exactly what they were so we could test the interactions between multiple event objects, various subsystems, and the user interface. I'm guessing these are mock objects, but I don't know why you wouldn't do this because without the objects of known values, you can't test a system.

Chamaeleon answered 17/10, 2008 at 22:49 Comment(0)
R
33

A mock object is not just an object with known values. It is an object that has the same interface as a complex object that you cannot use in test (like a database connection and result sets), but with an implementation that you can control in your test.

There are mocking frameworks that allow you to create these objects on the fly and in essence allow you to say something like: Make me an object with a method foo that takes an int and returns a bool. When I pass 0, it should return true. Then you can test the code that uses foo(), to make sure it reacts appropriately.

Martin Fowler has a great article on mocking:

Riel answered 17/10, 2008 at 22:56 Comment(0)
M
10

Think of the classic case of having client and server software. To test the client, you need the server; to test the server, you need the client. This makes unit testing pretty much impossible - without using mocks. If you mock the server, you can test the client in isolation and vice versa.

The point of the mock is not to duplicate the behaviour of the things its mocking though. It is more to act as a simple state machine whose state changes can be analysed by the test framework. So a client mock might generate test data, send it to the server and then analyse the response. You expect a certain response to a specific request, and so you can test if you get it.

Milton answered 17/10, 2008 at 22:55 Comment(0)
E
6

I agree with everything @Lou Franco says and you should definitely read the excellent Martin Fowler article on test doubles that @Lou Franco points you to.

The main purpose of any test double (fake, stub or mock) is to isolate the object under test so that your unit test is only testing that object (not its dependencies and the other types it collaborates or interacts with).

An object that provides the interface that your object is dependent on can be used in place of the actual dependency so that expectations can be placed that certain interactions will occur. This can be useful but there is some controversy around state-based vs. interaction-based testing. Overuse of mock expectation will lead to brittle tests.

A further reason for test doubles is to remove dependencies on databases or file systems or other types that are expensive to set up or perform time consuming operations. This means you can keep the time required to unit test the object you're interested in to a minimum.

Endotoxin answered 17/10, 2008 at 23:12 Comment(0)
J
2

Here's an example: if you're writing code that populates a database you may want to check if a particular method has added data to the database.

Setting up a copy of the database for testing has the problem that if you assume there are no records before the call to the tested method and one record after, then you need to roll back the database to a previous state, thus adding to the overhead for running the test.

If you assume there is only one more record than before, it may clash with a second tester (or even a second test in the same code) connecting to the same database, thus causing dependencies and making the tests fragile.

The mock allows you to keep the tests independent of each other and easy to set up.

This is just one example - I'm sure others can supply more.

I agree 100% with the other contributors on this topic, especially with the recommendation for the Martin Fowler article.

Jiggermast answered 4/12, 2008 at 11:50 Comment(0)
N
0

You might be interested in our book, see http://www.growing-object-oriented-software.com/. It's in Java, but the ideas still apply.

Nichellenichol answered 21/5, 2009 at 16:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.