1

I am trying to write a Unit Test for a function. This function is static and in a file, say FileA.cpp, though it is not a member of any class.

In FileA.cpp there is also a static variable defined. In another file say FileB.cpp there is a usage of this static variable.

My existing Unit Test code does not reference FileA.cpp, since none of its functionality is being tested so far. It does however test functionality of FileB.cpp. To facilitate this static variable reference, a fake variable is defined in Main.cpp of the Unit Test project (I am using GoogleTest framework).

But now I need to test FileA.cpp. When I add the file in the Makefile, I am getting a "multiple definition" error for this static variable.

I tried introducing a .h file (Say GlobalVars.h) with the same name in the Production and Testing project respectively and moving the variable there but it does not seem to fool the compiler. The FileA.cpp instance in the test project still tries to access the GlobalVars.h of the production code and I get a double definition again.

Any ideas how could I break this dependency?

Stephen Docy
  • 4,738
  • 7
  • 18
  • 31
georanto
  • 111
  • 11

1 Answers1

2

Instead of static variables, you should use variables defined inside an anonymous namespace. Those can be used as static global variable would be in a translation unit, but they have the advantage to be invisible outside the translation unit, not breaking the One Definition Rule.

// a.cpp
static int count = 0;
void f() { ++count; }

// b.cpp
static int count = 100; // breaks ODR
int g() { return count--; }

becomes

// a.cpp
namespace { int count = 0; }
void f() { ++count; }

// b.cpp
namespace { int count = 100; } // OK
int g() { return count--; }

Further reading:

YSC
  • 38,212
  • 9
  • 96
  • 149
  • According to SO question you link to, there is no essential difference between using a static variable and a variable declared in an anonymous namespace. – Clearer Apr 03 '18 at 08:25
  • "(...)In this case using a static or an unnamed namespace are back to being essentially two ways of doing the exact same thing.(...)" – Clearer Apr 03 '18 at 08:30
  • @Clearer The _intent_ (purpose) is the same, but there are subtle differences. That's what it says. – YSC Apr 03 '18 at 08:31
  • Unless I am mistaken, in the above example, each file affects its own **count**. But this is not what I want. The variable must remain shared among files of the Production code. When this code is used for Unit testing, then the fake static variable should be used instead.. I know it is ugly but I do not have (yet) the unit tests to support refactoring nor does my actual task justify large scale changes. – georanto Apr 03 '18 at 10:17