Unit testing non-exported classes in a DLL

Was searching a solution as well, maybe the following will be easier to maintain.

Add a new build configuration e.g. "Unit testing Debug" to the DLL project and change the Configuration Type to be "Static Library .lib" ("General"->"Configuration Type").

Then just add a dependency of your unit tests on this project, now everything should link together when you use new build configuration "Unit testing Debug". If you are using release builds for unit tests then you need to add another configuration with release optimizations.

So the benefits of this solution are:

  • low maintanability cost
  • single DLL/Static library project
  • don't have to manually link to .obj files

Drawbacks:

  • Extra configuration profile(s) will require some changes in your build environment (CI)
  • Greater compilation times

Update: We actually ended up using a different approach.

We added new "Test debug"/"Test release' configurations for every existing project that we have.

For .exe/.dll projects we disable the original main.cpp from compiling and replaced it with the one that instantiates the test framework (e.g. gtest) and runs all the tests, the tests are in separate .cpp files which are also excluded from compilation in regular configurations (Release/Debug) and enabled only in Test configurations.

For .lib projects we also have new "Test debug"/"Test release" configurations and there we convert the static library to be an .exe file and provide a main.cpp which instantiates the testing framework and runs the tests and tests themselves. Test related files are excluded from compilation on Release/Debug configurations.


Expanding on Tom Quarendon's answer to this question, I have used a slight variant of Simon Steele's response:

  • Create a test project (using whatever test framework you like, I use CppUnit).
  • In your test_case.cpp, #include <header/in/source/project.h>.
  • In the test project properties:
    • In Linker->General, add the source project's $(IntDir) to the Additional Library Directories.
    • In Linker->Input, add the .obj files to the Additional Dependencies.
  • Add the dependency from the test project to the source project in Project->Project Dependencies.

Again, the only maintenance overhead is the standard one for unit tests - to create the dependency on the unit(s) you want to test.


The solution I use for this is to build the same non-exported code into my tests DLL as well. This does increase build time and means adding everything to both projects, but saves exporting everything or putting the tests in the main product code.

Another posibility would be to compile the non-exported code into a lib which is used by both the DLL with exports, and the unit test project.