Problem

There are situations where we need to change or refactor some part of code where dependencies are impossible to replace in runtime for testing (ie. using dependency injection technique). Sometimes we have only header files of such entities with libraries available but only for different platform then we are working on.

Such situation happens when code is using free functions – ie. for memory management. How can we proceed with such situation to be able to follow rule – “cover and change” instead of “change and pray”?

Lets assume that we have piece of code which looks like this:

As you can see code is using external free functions called Resource_Reserve  and Resource_Free  for memory management.

We don’t have access to ResourceSystem implementation – it is delivered for us as library for embedded platform.

Possible solutions

To think about possible solution lets think about when/how we can replace one entity with its test double.

  1. Run-time – dependency injection – most common use for mocking purposes (require dynamic polymorphic types!)
  2. Compile-time – use of templates to replace one type to another (require static polymorphic types – duck-typing)
  3. Preprocessing – using preprocessor to replace one entity with another
  4. Linking-time – replace one implementation of given interface to another

I would like to present one solution which use linking time replacement and Google Mock framework.

Linking-time solution

Google Mock framework gives us tools for mocking polymorphic types (dynamic and static way). Unfortunatelly there are no support for dealing with free function mocking and non polymorphic types. Nevertheless there is one solution which can handle some of the cases and which is worth mentioning – lets see example.

Lets introduce ResourceSystemMock:

This is nothing new – common mock done using Google Mock framework, but it is not mocking free functions, right? At least for now it is not, but…

Lets look on cpp file:

What is happening here? Most important thing to notice is implementation of free functions void* Resource_Reserve(size_t size)  and void Resource_Free(void* resource) . The only thing they are doing is passing work to std::function static objects ( _reserve  and _free ) which are initialized inside ResourceSystemMock constructor (line 10 and 11). Which means that after creation of ResourceSystemMock  free function Resource_Reserve  will delegate its work to ResourceSystemMock::Resource_Reserve  method and free function Resource_Free  will delegate its work to ResourceSystemMock::Resource_Free  method – which as we all know are mocked by our Google Mock framework. That means that we can make expectations on Resource_Reserve  and Resource_Free  free functions via expectations on ResourceSystemMock::Resource_Reserve  and ResourceSystemMock::Resource_Free  methods.

Lets see some test code which will probable make things more clear.

At line 3 we create ResourceSystemMock  (called rs ) and then at lines 7-8 we make expectations on Resource_Reserve  and Resource_Free  functions – later they will be called inside Decoder::decode  function.

Lets see few tests which use such approach:

At line 9 we create ResourceSystemMock  as rs object (it is created inside test fixture – DecoderTestsFixture  – which will be used in every test).

And thats it – works like a dream! Unfortunately this solution has its own limitation that we cannot have more then one ResourceSystemMock  object created at a time (every creation of ResourceSystemMock  override _reserve  and _free  static variables – thats why we introduce assert in constructor that these variables has to be empty).

Expert question

Can we solve the problem with only one ResourceSystemMock  at time? I am waiting for proposals!

Code

Code from this blog post can be found on here: https://github.com/CppCodeReviewers/How-to-mock-free-function

About 

Service Delivery Manager and Scrum Master at Sii Poland company.

Since 2007 C++ enthusiast. C++11/14 evangelist - learn modern ways of developing in C++. Teaching TDD and agile way of coding.

  • googleplus
  • linkedin
  • twitter

One comment on “How to mock free function?

Leave a Reply