Listen to this post
When a unit being tested has a dependency, replace that dependency with a version that is only for testing, called a Mock Object. The Mock Object can be conditioned and inspected by the test.
Consider this situation. An application makes use of a webservice through an access object to obtain some critical information as part of its implementation. When testing the application, actually accessing the webservice will make the test too slow and/or will produce results the test cannot predict. Also, it is not certain the webservice will always be available when the test is running.
The webservice access object is replaced with a Mock that is predictable, fast, and guaranteed. The test can determine what the mock will return and inspect if (and how) the application accessed it.
Note: This is only one way to create a Mock. In this case, we are using direct inheritance (which may not always be desirable). There are many other ways, any of which could be preferable depending on circumstances.
Qualities and principles
The Mock replaces a dependency, controlling coupling for the purpose of testing. The test’s concern (application logic) is separated from the concern of the dependency, allowing the test to narrowly focus on the behavior it specifies. The interface of the mock is based on client need since the test takes the same position as the client would/will. The Mock is substitutable for the original dependency from the client point of view. The need/desire to make mocking possible in testing scenarios promotes the Open-Closed principle since mocks must be introduced without changes to application logic.
The Mock enables the test of the application under test. Mocks are inherently controllable by their own tests as well.
Questions and concerns
There are many ways of creating mocks, including the use of a mock object framework to automate their production. Mocks should be kept as simple as possible to avoid excessive testing scenarios involving them.
Additionally, it must be decided how to replace the real dependency with the mock version for while the test is running. This can be accomplished in various ways, including the use of a dependency injection framework.