Chapter 3. Frequently And Never Asked Questions

3.1. I have the following simple method but it does not compile when using the macros.
3.2. How should one organise production code and test code?
3.3. Why does mockpp uses that rather complicated Formatter class?
3.4. How can I mock a method which takes a reference to an incomplete class?
3.5. Is it possible to mock a function with a default parameter?
3.6. Where can I ask a question regarding mockpp?

3.1.

I have the following simple method but it does not compile when using the macros.


     const X& method(int p1);
    

Since mockpp emulates all method calls there is no variable to which you can return a reference. One solution is, to use a shadow method. The trick is to separate the mocking elements and the method in question which contains a real variable.


     MOCKPP_VISITABLE1(ClassName, shadow_method, int);

     X shadow_variable;  // the variable is a class member

     const X& method(int p1)
     {
        shadow_variable = shadow_method(p1);
        return shadow;
     }
    

A similar problem arises when you need to pass values back by a parameter reference. In this case you can use OutBound to return predefined values. Please also understand that this problem does not arise when using the mock method templates. In this case you have to create the forwarding method anyway.

3.2.

How should one organise production code and test code?

There is no general solution how to organise the sources to both run the tests and create a releasable binary without debugging and test code.

A flexible and clean approach is the one used within mockpp:

  • Place all the classes and functions of your production code into appropriate libraries. All the source code for the according library is in a separate subdirectory.
  • Create a minimalistic application source file with your main() in a top-level directory. This application uses the former libraries.
  • Create a subdirectory tests within each sub-project which contains all the test files needed. Depending on your test framework the test files form a library or an executable. Upon execution the above libray with the production code is linked dynamically.

So the layout of your project tree might look like this:


       projectroot
                 \_ main()
                 |
                 \_ subproject1
                 |             \_ tests
                 |
                 \_ subproject2
                               \_ tests

     

3.3.

Why does mockpp uses that rather complicated Formatter class?

The two reasons to use this approach were enhanced readability and better support for internationalisation:

Simply take the example from the handbook:


    Person pers("Bob", 6);
    String  format = "%4 says: %3 plus %2 gives %1";

    string one = "one";
    string two = "two";
    string three = "three";

    format << three   // %1
           << two     // %2
           << one     // %3
           << pers;   // %4

    std::cout << format << std::endl;
  

The format string already gives you a good idea about the result, you only have to substitute the % by the actual values.

Please also understand that I intentionally reverted the order of the %-substitutes to show this possibility. More about the need for this below.

On the contrary it is far more difficult to understand the outcome with standard streaming operators:


    cout << pers.toString()
         << " says: "
         << one
         << " plus "
         << two
         << " give "
         << three;
  

I am pretty sure you will forget the one or the other space which separates for example the literal "plus" from the variable "two".

The other important point is: you can't translate the second solution reasonably. Translating "says:" and "plus" separately and concatenating them like above often results in the nonsense you get when you read manuals for devices from the far east. Often also the order of the substituted words change in the translated version. In this case the translator simply would swap %1 and %2.

Maybe you don't find it worth the effort but english is not the only language on earth, so why not prepare a nice way to translate the library? Someone interested in a translated version simply uses xgettext to collect the strings, translates them with a simple editor and replaces macro mockpp_i18n() with the according call from the standard intl package.

And overloading operator<< is similar to the standard iomanip functions:


  class CA
  {
    String toString()
    {
      ...
    }
    ...
  };

  String & operator << (String &formatter, const CA &o)
  {
    return ::operator<< (formatter, o.toString());
  }
  

Additionally you can use MOCKPP_ENABLE_DEFAULT_FORMATTER to generate a default operator<< which outputs the class name which is often enough.

3.4.

How can I mock a method which takes a reference to an incomplete class?


   class Interface
   {
      public:
         void someMethod(const Interface& iface) = 0;

   };

   class MyMock : public VisitableMockObject
                , public Interface
   {
     public:

      MyMock()
        : VisitableMockObject("MyMock", 0
        , someMethod_mocker("someMethod", this)
      {}

      void someMethod(const Interface& iface)
      {
        someMethod_mocker.forward(iface);
      }

      VisitableMockMethod1<void, Interface> someMethod_mocker;
   };

   

Somewhere deep in the library mockpp needs a variable to hold the contents behind the reference. Since the class is incomplete the copy contructor will always fail. But it should work to use a pointer instead the reference. The interface of the mocked method remains the same but all the mockpp specific stuff uses the pointer:


   void someMethod(const Interface& iface)
   {
     someMethod_mocker.forward(&iface);
   }

   VisitableMockMethod1<void, Interface * > someMethod_mocker;
   

3.5.

Is it possible to mock a function with a default parameter?

Due to the internal macro structure it is not possible to add default parameters in mock methods. Providing this possibility would require another set of macros which is not reasonable.

But you don't actually need it. A mock object is derived from a more or less abstract base class. Since default values should never change, the according default value is also in the base class, even it is pure virtual. The production code should only know about the base class which contains the default value, so all you need is already available.

3.6.

Where can I ask a question regarding mockpp?

Send a mail to the according mailing list or point your browser to the forum.