2

There seems to be a lot of question regarding "when to mock". But I did not get an answer on my question so far. It can be, I do not know a specific search request that would point me to the answer.

Imagine we have a class (MyClass). Imagine that this class has methods that can return both std::string and a wrapper class (MyStringWrapper defined in another library) object. MyStringWrapper is not exactly aggregator (we can consider to use struct here, but let's prefer a class for this particular example), since its setter has one if and several copy operations. Now, there is a 3rd class (UserClass) that uses MyClass and MyStringWrapper class.

As a good SW developer, I would like to unit-test my UserClass (as many refer "to smell a code"). For unit-testing I would use gtests and gmock to create a mock of the MyClass (let's call it MyClassMock). However, I remember that somewhere it was told "you have to mock everything, which is defined in another library/3rd party library". Both std::string and MyStringWrapper are defined in 3rd party libraries.

Now the question. So, should I in this case create mocks for both std::string and MyStringWrapper?

You can imagine the usage of the returned std::string/MyStringWrapper object as

if(myreturnedstdstring.empty())
  return 1;

if(mywrapperobject.failed())
  return 100;

I was asked in comments here Is there a point to unit tests that stub and mock everything public?

create another topic.

  • 7
    no. you dont have to mock everything just because its in the thrid party lib. esp not standard types – Ewan Sep 14 at 15:43
  • 2
    Whenever a statement contains "everything" (as in "you have to mock everything"), you're always going to need some common sense as to what "everything" includes. People rarely mean "everything" literally, it's a matter of context. If I tell you I was so hungry I ate everything in the fridge, would you assume I ate the fridge light and the shelves as well? No, you'd assume I ate all the food. Because that makes contextual sense. – Flater Sep 15 at 10:53
  • @Flater In some cases we have to assume the worst :) But yes, you are totally correct as well as Ewan – user1415536 Sep 16 at 12:56
4

Anything in std:: is part of the language and should not be mocked. Your string wrapper, if not part of the "unit" under test may be mocked but IMHO and experience a wrapper like that is generally so light weight that the mock would essentially reproduce the code. In that case I would not mock it. However if the wrapper could change in the future you should mock it if you want a stable unit test. On the other hand having a test fail when an incompatible change is made to the wrapper would be good, but harder to track down since the error will be in some other unit.

| improve this answer | |
6

I remember that somewhere it was told "you have to mock everything, which is defined in another library/3rd party library".

That may have been the advice at one time, but it is not the advice that is commonly given today.

The current advice is to use mock sparingly to help the these goals of unit-testing:

  • The tests can be executed fast, in parallel or in any order and at any time. This implies that components that interact with persistent storage (databases, filesystems), slow (network) connections or environmental conditions that you can't easily control (e.g. time) are a candidate for mocking.
  • All paths through the code-under-test can be exercised. If a certain (error) response from a dependency can't be easily triggered with the real code, then that could be a reason to mock that dependency.

Simple datatypes, like strings, your MyStringWrapper or even containers don't fit those points, so there is no reason to mock them.

| improve this answer | |
  • I wish I could marked two answers as accepted answers. – user1415536 Sep 16 at 12:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.