I'm unit testing a class in C++ and some of the public methods call private ones. I know convention is to test the public interface, but the classes' functionality depends on ho开发者_运维知识库w these private methods in turn invoke other classes and their methods. This is similar to the public interface in the sense that no matter what happens to the private function it will still conform to the API.
I've been able to mock the classes invoked in the private function for the most part to test the API, but in a few cases I've run into places where the standard library is referenced and haven't managed to mock it. Are there any tricks to mocking standard library classes etc? Or should I skip them?
-- Also I'm not able to either change the source or use mocking libraries.
If you really wish to mock the standard library then the easiest (possibly only) approach is to instrument your code correctly. That is, instead of using the headers and std
namespace directly you'll have to use an intermediary name.
So invent a namespace, call it mstd
. In your mocked mode this will be your mock namespace. In non-mock mode this will simply be an alias to std
.
For header files you'll have to avoid including the standard headers directly, but use a mocking layer. So instead of including <map>
you could include <mk-map>
. This header file will then decide between the standard library and your version. Perhaps like this:
#ifdef MOCK_MODE
#include "mock/map.hpp"
#else
#include <map>
#endif
You could alternately give a different include path to your compiler, one that comes before the standard libraries. However, since you have to alias the namespace anyway you'll still have to modify all of your code -- thus it's just as easy to include these special headers.
This is about the only way I can see this working. Note that using LD_PRELOAD or any library technique will not work: the C++ standard library is made up of a lot of template classes and inline functions. You need to replace them right at compile time.
If you're trying to do some whitebox testing of a class's private methods, maybe your compiler will let you bypass the access control? GCC at least allows -fno-access-control
, which I have used with great success for both whitebox unit tests and introspection into data structures, i.e. hash collisions in unordered_{set,map}
.
Skipping access control also lets you muck directly with the member variables in between other calls, if you really want to be devious.
For such purposes, I would recommend you Typemock Isolator++ API, that allows to mock global methods without any redefinings. Look, how easy it is:
FAKE_GLOBAL(fopen);
WHEN_CALLED(fopen(0,0)).Return(_anotherFile);
And you don't even need to change the source code.
Is it really necessary to make mockups of the standard library? Sure, it's possible that the standard library functions have bugs, but your mockups are probably more likely to have bugs than they are.
I would say to just use them as they are. If you track down a test failure to the standard library, then you've found a standard library bug. And, at least for the near term, you will probably have to find a way to work around such bugs.
精彩评论