18

I am working on a procedural C/C++ project. The public interface consists of 4 functions, each with fairly complex tasks. There are helper functions declared in the same cpp file, in an unnamed namespace. The test framework being used is GTest.

However, some of these helper functions are becoming complex enough to require their own unit testing. Normally, I would refactor these helpers into their own testable units, but the project requirements state everything needs to be in the one cpp, and only the specified functions can be publicly visible.

Is there a way I can unit test the helper functions while minimizing coupling, and following the project requirements as closely as possible?

A possible solution I had was to use a macro to turn the namespace into a named one for testing, and unnamed for production. However, that seemed a bit messier than I would like.

  • Possible duplicate of [How do I test a class that has private methods, fields or inner classes?](https://stackoverflow.com/questions/34571/how-do-i-test-a-class-that-has-private-methods-fields-or-inner-classes) – Raedwald Dec 14 '17 at 13:20

1 Answers1

17

Both definitions and declarations in an anonymous namespace are only visible within the same translation unit.

There are two approaches you can take to unit test these private functions.

You can #include the entire .cpp file being tested in your _test.cpp file. (#includeing .cpp files is not a good way to reuse code - you should not do this in production code!)

Perhaps a better approach is to move the private code into a foo::internal namespace, where foo is the namespace your project normally uses, and put the private declarations in a -internal.h file. Your production .cpp files and your tests are allowed to include this internal header, but your clients are not. This way, you can fully test your internal implementation without leaking it to your clients.

johnsyweb
  • 129,524
  • 23
  • 177
  • 239
  • 7
    For the second method, moving objects to named namespace means it will keep reference-able runtime identity, and it seems voiding the reason of using anonymous namespace - completely prohibiting any access from out of the compilation unit… Also it seems allowing accidental name clash… – eonil Nov 24 '13 at 21:56
  • 1
    Really like your first idea. Wondering if someone will shoot me for doing it. – AturSams Sep 29 '15 at 14:40