While testing, it is frequently useful to be able to isolate the component being tested, and making it interact with "fake" objects, known as mocks in the Object-Oriented literature.
Liberty Eiffel's mock implementation is quite straightforward: it takes a class to mock, and produce two classes: the mock implementation, and a test driver.
- Instances of the mock implementation class will be used to interact with the component being tested.
- Instances of the test driver class will be used by the test scenario to "prepare" the behavior of the mock implementation instances.
There is only one requirement: the class to be mocked must be deferred.
eiffeltest is also able to automatically generate mocks.
Calling mock directly
The tool takes one parameter: the name of the class to mock, which must be deferred. It generates two classes:
- the _MOCK class, which is the implementation of the class to mock;
- the _EXPECT class, which is the test driver, used in test scenarios.
There are options to change the name of the generated classes.
Using the test driver
The test driver, or expect class, allows to prepare the behavior of the mock instance.
When the tester creates an expect instance, a mock instance is created by the test driver. It is available using the mock feature.
For each deferred feature of the class to mock, the test driver exposes:
- A feature with the same name, that takes the same arguments as the original function, and returns an expectation object (more on that below);
- A feature with the same name and a __match suffix, only if the original feature takes arguments. In that case, the arguments are matchers, thus allowing a greater liberty on how to match arguments. The feature also returns an expectation object.
The expectation object is used when the corresponding feature is called on the mock object (presumably by the component being tested). When building the test scenario, the expectation object is used to tune how the mock object behaves when the feature is called:
- What object to return (if it is a function)
- If a function must be called as side-effect
- The number of times the feature is expected to be called
Eiffeltest brings the following features:
- .mock files are read by eiffeltest. Each line must be a file name of a class to mock. Eiffeltest will call mock on each class.
- EIFFELTEST_TOOLS contains a feature scenario, used to prepare the test scenario using mocks
There is an example of such a usage in the test/tools/mocker directory in Liberty Eiffel source tree.