1

I have been trying to access private members of a class in a base project for unittesting the public void methods of the class in another project. These methods modify the private members, so this is my motivation. I have to work with visual studio 2008 for this.

Now the Microsoft tutorial suggests to compile the base project into a static lib, since that would allow to access to private members. https://msdn.microsoft.com/en-us/library/hh419385.aspx However, after adding the reference on the project and inputting the .lib to the linker, I still get the error that the private member cant be accessed. However the .lib is obviously found and read.

When i declare my Test project as a friend class in the base class, it works as expected, but I'm trying to change as little as possible (nothing) on the base code.

I just wonder what's behind Microsoft's suggestion. Is it even supposed to work? Is my version of Visual Studio (=2008) the Problem? Thanks for your help.

I read about ways to access private members, but they are all rather messy and not what I mean to do. For example: Can I access private members from outside the class without using friends?

  • You will need a friend class to access it's private members – Asesh Jan 10 '18 at 11:38
  • There are different opinions here - some people argue that you should test that the public interface works correctly, not how it is implemented. Should the unit tests fail if you change the implementation but produce the same results? – Bo Persson Jan 10 '18 at 12:00
  • Regarding the base project itself, I should mention that it's a GUI programmed with the QT framework. It is my task to find the best possible way of testing classes and methods in general. I am using QTest for this. Originally, the base projects are compiled as .dll, but i was just curious if compiling as a static lib would solve the privacy issue. If you have any suggestions on how to solve such a project in general, i would be thankful, since im a student with only little programming experience. – Schnuffel Hasi Jan 10 '18 at 12:28
  • Thats why the Methods and the class dont really produce any result at all, except for displaying a form for example. – Schnuffel Hasi Jan 10 '18 at 12:35

1 Answers1

0

The Microsoft documentation you have read has the air of being written by a summer intern and is misleading.

Building a static library from object files compiled from C++ source can have no influence on the C++ access status of class members. That access status is determined by the class definition in the header file. Whether or not you put the associated object file into any kind of archive makes no difference to the header file, or the class definition.

When you read:

The unit tests must use private functions and data, and the code under test can be built as a static library:

Change the project under test so that it is compiled to a .lib file. Add a separate test project that references the project under test.

what private data and functions should mean (charitably interpreted) is data and functions that are not exported for dynamic linkage from a DLL. Such non-DLL-exported data or functions might nevertheless have external (global,public) linkage and be public members of C++ classes; and in the general case, if they are members of C++ classes then they must have public or at least protected C++ access if unit tests are to access them without benefit of C++ friendship(s) declared in the classes under test.

So the C++ friendship solution that you have already found is as right as any. You might consider using the preprocessor and conditional compilation to make the intrusive friend declarations exist only in the context of the unit testing project.

But pay heed to @BoPersson's comment. The probing or exercising of private class members in unit tests at all is a questionable practice. The overt behaviour of a C++ class is completely defined by its public/protected interface. So what business have your unit tests with the internal implementation? Find a convincing answer before proceeding.

Mike Kinghan
  • 55,740
  • 12
  • 153
  • 182