I use an approach similar to Jon's, but instead of creating a specialized interface for the current time only (e.g. Clock ), I usually create a special test interface (say, MockupFactory ). I put there all the methods that I need to check the code. For example, in one of my projects, I have four methods:
- one that returns the layout database client;
- which creates a mock-up notifier object that notifies the code of changes to the database;
- which creates the java.util.Timer layout, which runs tasks whenever I want;
- which returns the current time.
The class under test has a constructor that takes this interface among other arguments. Anyone who does not have this argument simply creates a default instance of this interface that works "in real life." Both the interface and the constructor are closed to the package, so the testing API does not flow outside the package.
If I need more simulated objects, I just add a method to this interface and implement it in both test and real implementations.
Thus, I develop the code suitable for testing, first of all, without imposing too much on the code itself. In fact, the code becomes even cleaner as the factory code is assembled in one place. For example, if I need to switch to another database client implementation in real code, I need to change only one line, and not look around the constructor reference.
Of course, as in the case of John, he will not work with third-party code that you cannot or cannot change.
Sergei Tachenov Oct 23 '13 at 5:56 on 2013-10-23 05:56
source share