3 ms·
I have seen a lot of projects that use interfaces in C++ or Java just to be able to mock the tests. This puzzled me. If it is known that the there will be exac
by fpoling 6y ago
I have seen a lot of projects that use interfaces in C++ or Java just to be able to mock the tests. This puzzled me.
If it is known that the there will be exactly 2 implementations of the interface, one real one and one for mocking, then do not use interfaces. Instead use a global flag and at relevant places instead of calling interface’ methods just test the flag and branch for test/non-test code. If the flag is a compile-time constant, then compilers will be able to eliminate the checks completely. If it is not a constant, then due to branch prediction over a simple global the runtime impact will be minuscule, much smaller than with interfaces even without advanced link-time optimizations.
The big plus of this approach is that test-only coupling is explicit and easily grepable. Another one is that if test mocking requires complex changes to the control flaw, providing that level of control via interfaces often leads to complex and awkward interfaces, but with the flag it is very straightforward to get the necessary behavior.
- Leherenn 6y agoIt massively hurts readability and can quickly become messy in my experience. If you're running on multiple targets and testing on host, then you have an #ifdef spaghetti in no time. In all the codebases I have worked on, they started like this because it is easy, but then moved on to interfaces/templates because maintainability is an issue with this method.
- fpoling 6y agoI worked on QT application where we observed the opposite. As typical with QT the code was a collection of components that were glued together in the main application. For testing it turned out adding few flags to the application was enough to implement unit and integration test driver. Surely there were few ifs, but the code was very readable and such design allowed very straightforward implementation of integration tests.