In computer science, a mock object is an object that imitates a production object in limited ways.
A programmer might use a mock object as a test double for software testing. A mock object can also be used in generic programming.
Analogy
A mock object can be useful to the software tester like a car designer uses a crash test dummy to simulate a human in a vehicle impact.
Motivation
In a unit test, mock objects can simulate the behavior of complex, real objects and are therefore useful when a real object is impractical or impossible to incorporate into a unit test. If an object has any of the following characteristics, it may be useful to use a mock object in its place:
- it supplies non-deterministic results (e.g. the current time or the current temperature)
- it has states that are difficult to create or reproduce (e.g. a network error)
- it is slow (e.g. a complete database, which would have to be prepared before the test)
- it does not yet exist or may change behavior
- it would have to include information and methods exclusively for testing purposes (and not for its actual task)
For example, an alarm clock program which causes a bell to ring at a certain time might get the current time from a time service. To test this, the test must wait until the alarm time to know whether it has rung the bell correctly. If a mock time service is used in place of the real time service, it can be programmed to provide the bell-ringing time (or any other time) regardless of the real time, so that the alarm clock program can be tested in isolation.
Technical details
Mock objects have the same interface as the real objects they mimic, allowing a client object to remain unaware of whether it is using a real object or a mock object. Many available mock object frameworks allow the programmer to specify which methods will be invoked on a mock object, in what order, what parameters will be passed to them, and what values will be returned. Thus, the behavior of a complex object such as a network socket can be mimicked by a mock object, allowing the programmer to discover whether the object being tested responds appropriately to the wide variety of states such mock objects may be in.
Mocks, fakes or stubs
The definitions of mock, fake and stub are not consistent across the literature. Nonetheless, all represent a production object in a testing environment by exposing the same interface.
Regardless of name, the simplest form returns pre-arranged responses (as in a method stub) and the most complex form imitates a production object's complete logic.
Such a test object might contain assertions to examine the context of each call. For example, a mock object might assert the order in which its methods are called, or assert consistency of data across method calls.
In the book The Art of Unit Testing mocks are described as a fake object that helps decide whether a test failed or passed by verifying whether an interaction with an object occurred. Everything else is defined as a stub. In that book, fakes are anything that is not real, which, based on their usage, can be either stubs or mocks.
Setting expectations
Consider an example where an authorization subsystem has been mocked. The mock object implements an <code>isUserAllowed(task : Task) : boolean</code> method to match that in the real authorization class. Many advantages follow if it also exposes an <code>isAllowed : boolean</code> property, which is not present in the real class. This allows test code to easily set the expectation that a user will, or will not, be granted permission in the next call and therefore to readily test the behavior of the rest of the system in either case.
Similarly, mock-only settings could ensure that subsequent calls to the sub-system will cause it to throw an exception, hang without responding, or return <code>null</code> etc. Thus, it is possible to develop and test client behaviors for realistic fault conditions in back-end sub-systems, as well as for their expected responses. Without such a simple and flexible mock system, testing each of these situations may be too laborious for them to be given proper consideration.
Writing log strings
A mock database object's <code>save(person : Person)</code> method may not contain much (if any) implementation code. It might check the existence and perhaps the validity of the Person object passed in for saving (see fake vs. mock discussion above), but beyond that there might be no other implementation.
This is a missed opportunity. The mock method could add an entry to a public log string. The entry need be no more than "Person saved", or it may include some details from the person object instance, such as a name or ID. If the test code also checks the final contents of the log string after various series of operations involving the mock database, then it is possible to verify that in each case exactly the expected number of database saves have been performed. This can find otherwise invisible performance-sapping bugs, for example, where a developer, nervous of losing data, has coded repeated calls to <code>save()</code> where just one would have sufficed.
Use in test-driven development
Programmers working with the test-driven development (TDD) method make use of mock objects when writing software. Mock objects meet the interface requirements of, and stand in for, more complex real ones; thus they allow programmers to write and unit-test functionality in one area without calling complex underlying or collaborating classes.
See also
- Abstract method
- Dummy code
- Method stub
- Mock trainwreck
- Test double
References
External links
- Test Doubles: a section of a book on unit testing patterns.
- All about mock objects! Portal concerning mock objects
- Unit testing with mock objects IBM developerWorks
- Mocks Aren't Stubs (Martin Fowler) Article about developing tests with Mock objects. Identifies and compares the "classical" and "mockist" schools of testing. Touches on points about the impact on design and maintenance.
