How to test private member functions of a class using QTestLib? - c++

I am using QTestLib for Unit Testing and i ask myself how to test private member functions of my classes. I would like to build a test suite for an in-house shared library.
What strategies do i have in Qt's context for this ?
I thought that testing private member functions through public members functions could be a good starting point :
class A {
public:
// add an extra function that is only relevant for testing
int value() const {
return theFunctionIWantToTest();
}
private:
int theFunctionIWantToTest() {
// implementation ..
}
}
But the problem is that i don't need this getter in the class A after testing.
I am not very experienced with QTestLib and so far i could not find anything in Qt's Doc related to this specific point.
Thanks.

Four possible solutions in reverse order of personal preference:
Set #define private public before include the class header. Non-portable unfortunately. (or luckily as some will say).
Declare your QTestLib test class to be a friend of class A
Move the gist of the function into a dedicated function in a separate file that is clearly marked as private API and forwared the call from the member function. Think of the a_p.h headers used by Qt itself.
Settle on testing the public interface only. I.e. either give up on the goal to test private functions or accept that the function simply should be public in the first place.

Related

Is there a way for me to wildcard a friend class in C++?

I'm using gtest to unit test a cpp class. Consider a situation in which I'd like to make the test class a friend of the actual class, so it can unit test its private state. This works fine for me. The problem is that while using the very helpful TEST_P macro which allows you to parameterize test instantiation, the framework mangles the test name a bit.
So I have something like
class FooTester {
FooTester() {}
}
TEST_P(FooTester, TestCoolFeature) {
// test my cool feature that needs access to Foo's internal state
}
which is great but to allow this I must provide
class Foo {
friend class FooTester_TestCoolFeature;
}
we can see through macro magic gtest creates a new class I haven't explicitly declared which is a combination of the test class and the test method name.
This is ostensibly fine but a bit ugly. It would require me to add a new friend class for each new test method which requires this access. The only real, if unlikely, problem is that if gtest were to change its implementation and mangle the class names differently, it could break my tests.
Is there a way to use some #define magic or similar to declare all FooTester* classes as friends?
Do not use friend classes for that. If you would like to access Foo from FooTester, inherit it publicly:
class FooTester : public Foo
{
FooTester() {}
}

What's the best practice to check target object's private variable in unit test code using gtest framework?

I'm using gtest as my unit test framework. In my work, it's a common case that a public method modifies some private variables in the object. These variables stores the "states" of the object and has affects to the object's behavior. For example:
class ConferenceRoom {
public:
void AddUser(const std::string& user_info);
void OnDataReceived(uint32_t user_id, const std::string& message);
private:
// Map[user_id] --> User
std::unordered_map<uint32_t, User> user_map_;
};
I want to test the public method AddUser with various good/bad user_info, but I can't access the private variable user_map_ directly to check if this map is changed as I expected. I don't know what's the best practice for this case? I know some solutions:
Using friend to access ConferenceRoom's private variable, this will make ConferenceRoom aware test code.
Declare user_map_ as protected, and using TestRoom inherits ConferenceRoom, then check the map in TestRoom.
Add a virtual private method const std::unordered_map<uint32_t, User>& GetUserMap() const; using TestRoom inherits ConferenceRoom and overrides this virtual method, then access private user_map_ with GetUserMap.
I'm sure there must be some other solutions for this case. In my mind, the solution should be isolate class ConferenceRoom with test code, and the class ConferenceRoom can be delivered to use clearly without any strange code. What your best practice?
Using a small template magic code as demonstrated in this answer already, you may access the private variables directly without modifying the source.
For your code, you have to do following:
ALLOW_ACCESS(ConferenceRoom, user_map_, std::unordered_map<uint32_t, User>); // setup
// ... class declarations ...
ConferenceRoom object;
auto& user_map_ = ACCESS(object, user_map_);
// use `user_map_`
Demo.

How can I open class only to test class?

I'm mainly a Java developer and wonder about structure when writing unit test in kotlin,
Assuming there's no package-private in kotlin
private to restrict visibility to the file
internal to restrict visibility to the module
How can I open class only to test class ?
Must I write test inside kotlin class or open class to all module (internal)?
What's the kotlin way to open method for unit test only?
EDIT
Found similar question/request in kotlin discuss by #bentolor:
How am I supposed to do unit / whitebox testing properly? I want to write test code which tests class-internal functionality which I do not want to expose to other classes except my test class at all.
The package protected visibility is an excellent way to achieve this. Whereas Kotlin now requires me to make these methods effectively public and litter the visible API of my component all-over the project be able to test them.
In my view internal is more or less public as it has a much larger scope. Most projects have sth. around 1 - 5 “modules” in the Kotlin sense.
Really strongly asking/advocating for package-local visibility here.
Formally it is not possible to do this honestly on JVM, because class couldn't be open for subset of possible interiters.
However it can be partially done by the following trick:
open class SomeClass internal constructor(val configurableParameter: Int) {
companion object {
private const val defaultInput = 123
fun create() = SomeClass(defaultInput)
}
}
The constructor of this class can be called only from the same module (or from tests). And class is public, so anyone can use it. However from external modules you have only two ways of the class construction: companion object or reflection.
And finally you couldn't inherit from this class at any other modules, because constructor is internal.
For Android developers only, there's AndroidX VisibleForTesting annotation
Denotes that the class, method or field has its visibility relaxed, so that it is more widely visible than otherwise necessary to make code testable

TDD in C++. How to test friend functions of private class?

if I have a class with a helper (private member) class within it, like this
class Obj;
class Helper {
friend class Obj;
private:
int m_count;
Helper(){ m_count = 0;}; // Note this is a private constructor
void incrementCount(){
++m_count;
};
};
class Obj {
Helper *m_pHelper;
// note that this is a private getter
int getHelperCount() { return m_pHelper->m_count; };
// the public API starts here
public:
Obj() { m_pHelper = new Helper(); };
void incrementCount(){ m_pHelper->incrementCount(); };
};
So how may I TDD such a system?
auto obj = new Obj();
obj->incrementCount();
// what to assert???
That is my question and the following is just some background.
Response to some answers and comments.
If noone outside the class should be interested, then your tests should not be interested either. – Arne Mertz
If nobody is interested in the value outside the class, why are you – utnapistim
Even if no one outside needs the value, I may still want to know that if it's set correctly, as it is used by other self contained internal method of the class that use that value. Maybe the value is the speed where the controller will use it to update the model. Or maybe it's the position where the view will use it to draw something on the screen. And in fact all other components of Obj would be able to access that variable. It may be a bad design issue, and in this case I would like to know what better alternatives I can have. The design is listed in the background section at the bottom of this post.
define private public - Marson Mao
Love this ingenious abuse of keywords haha. But may not be concluded as the best solution just yet.
You need to "expose" the friendship relation in the header of your class. Thus you have to acknowledge there the existence of a class used to test yours.
If you use the pImpl idiom, you could make the members of the pImpl itself all public, the pImpl itself private and give your unit tests access to the pImpl - CashCow
Does this mean that I should friend the test in my original class? Or add extra "test" methods to it?
I just started TDD very recently. Is it common (or better is it good) to intrude the original class with test class dependency? I don't think I have the appropriate knowledge to judge. Any advice on this?
Miscellaneous: AFAIK TDD is not just writing test, but instead a development process. I have read that I should only write tests to the public interface. But the problem is, like the situation in question, most of the codes etc are contained within private class. How may I use TDD to create these codes?
Background
FYI if you would like to know why I am making a private class:
I am developing a game from cocos2dx. The game engine adopts a Node tree structure for the updates, rendering etc and every game object would inherit from a Node class provided in the engine. Now I want to implement the MVC pattern on a game object. So for each object I basically created a Object class with 3 helper classes corresponding to each of the MVC components named ObjectModel, ObjectView, ObjectController. Theoretically no one should access the MVC classes directly and would only be accessed somehow through the Object class so I make the 3 of them private. The reason of making the MVC components explicitly as classes is because the View and Controller are updating at different rates (more specifically the Controller performs frame dependent updates, while the View do a simple interpolation based on the model data). The Model class is created purely for religious reasons lol.
Thanks in advance.
How to test friend functions of private class?
Thou shalt not!
A class (or module or library or whatever) exposes a public interface for a reason. You have the public interface (which is geared for client use, so it has invariants, preconditions, postconditions, side-effects, whatever - which can and should be tested) and implementation details, that allow you to implement the public interface, easier.
The point of having a private implementation, is that you are allowed to change it as you please, without affecting other code (without affecting even tests). All tests should pass after you change your private implementation, and client (and test) code should (by design) not care at all that you changed the private implementation.
So how may I TDD such a system?
TDD your public interface only. Testing implementation details means you end up coding to an implementation, instead of an interface.
Regarding your comment:
The problem is I don't even have a getter in the public interface. So how can my test check that the value is 0 or 1? And the getter is intentionally made private as no one should be interested in the value outside the class
If nobody is interested in the value outside the class, why are you (i.e. why would you wish to test for it?)
The #define private public trick can have side effects with the way some compiler are mangling function symbols (Visual c++ compiler is including access specifier in its name mangling)
You can also change visibility with the using statement :
struct ObjTest : public Obj
{
using Obj::incrementCount;
}
But like other people said, try to not test private stuff if possible.
I have encounter such problem when I was writing unit test as well.
After some searching I decided the most effective way is to add this in your Test.cpp:
#define private public
NOTE: add this before your desired include file, maybe your Obj.h, for example.
I think this method looks crazy but it's actually reasonable, because this #define only affect your test file, so all other people using your Obj.h is totally fine.
Some reference:
Unit testing of private methods
I vote, as #Marson Mao says, for #define private public.
If you want to control what to make private or public a bit more, you can do this in yourtests.cpp
#define private public
#include "IWantAccessViolationForThis.h"
#undef private
#include "NormalFile.h"
This way you can have a bit more control and try to do this trick in as few places as possible.
Another nice property of this approach is that it is non-intrusive, meaning that you don't need to clutter your real implementation and header files with #ifdefs for testing and not testing modes.
Your friend has full access to the class that it is a friend of. This might be done for many reasons and one of those could well be for unit-testing purpose, i.e. you want to be able to write a unit test that can call private members of the class and check the internal variables show what you would expect them to show, but you do not want that to be part of the public API.
You need to "expose" the friendship relation in the header of your class. Thus you have to acknowledge there the existence of a class used to test yours. No worries, you develop in the real world and classes are tested.
In order to write a unit test you will want to implement that class to provide protected member functions (probably static ones) that call all the relevant private functions or get the private members, and then you write classes that derive from yours. Note that those will not have direct access as friendship is not inherited, thus the static protected members.
If you use the pImpl idiom, you could make the members of the pImpl itself all public, the pImpl itself private and give your unit tests access to the pImpl (through the same model as above). This is now simpler as you only need to create one method for your "tester".
With regards to data members of a class, in recent years I have been known to put all these into a struct, i.e. have them all public, and then for the class to have a private instance of that struct. It can be easier for handling this kind of thing, and also serialisation / factories to your class, where they can create the struct which is all public, then construct your class from it.

Is it possible in Qt to unit test (access) private methods?

I'm writing unit tests for my app, and now I've stumbled on a class in which I should test private methods. This could be result of poor design of particular class, but I must do it. Is there any way in Qt to call private methods, maybe using QMetaObject or something similar ?
For unit testing I am using QTestLib framework.
The proper (read annoying) answer is that you should not be testing private methods, those are implementation details ;-).
OTOH -- have you thought about conditionally declaring them protected/private depending on whether you are in testing or no and then extending? I've used that to get me out of a similar pinch in the past.
#ifdef TESTING
// or maybe even public!
#define ACCESS protected
#else
#define ACCESS private
#endif
/* your class here */
class Foo {
ACCESS
int fooeyness;
}
// or better yet, place this in a different file!
#ifdef TESTING
/*
class which extends the tested class which has public accessors
*/
#endif
Solution 1, quick and easy: make the test class(es) a friend of the public one.
class Foo {
// ...
private:
friend class FooTest;
};
This way your FooTest class can access all members of the public class. However, this way you need to modify the original class every time you want to access private data from a different test, and you leak information about the tests in the public API, and you possibly open up for class naming conflicts (what if there's /another/ FooTest class around?), and so on.
Solution 2, aka properly done: don't put private methods in the public class, but make a private class with public methods.
class Foo {
//
private:
friend class FooPrivate;
FooPrivate *d;
};
FooPrivate gets declared in its own header, which may not be installed, or stay in a include-privates/ subdirectory, or whatever -- i.e. it stays out of the way for normal usage. The public class stays clean this way.
class FooPrivate {
public:
// only public stuff in here;
// and especially this:
static FooPrivate *get(Foo *f) { return f->d; }
};
The test then includes the private header and calls FooPrivate::get(fooObj) to get the private class instance and then happily uses it.
I disagree with the "private members are implementation details" mentality, in my mind that roughly translates to "test only part of your code".
I can related to "units are units" argument, but why not try to cover as much of your code with tests as possible, even inside units? Aka. giving your units a thorough rectal examination.
And with this image in mind, one approach that I have been using frequently that is not mentioned in the other answers is to do the following:
Always declare members you want to test as protected in stead of private in your code.
Subclass your class in the testcode and simply make the selectors you need or simply write the test-code directly as members in that sub-class's implementation.
NOTE: You have to be careful with classes that rely on complex instantiation patterns to ensure that you construct them correctly (read: call the original class' constructor from the subclass ctor).
I have found more convenient way to do this. First, all private methods should be private slots.
Then you create an instance of the class:
Foo a;
Then we can use QMetaObject::invokeMethod to call any slot that method has (public or private). So if we want to call method Test, we can do it like this:
QMetaObject::invokeMethod(&a, "Test", Qt::DirectConnection);
Also, we can have return value and send arguments ... Actually, everything is answered here: http://doc.qt.nokia.com/stable/qmetaobject.html#invokeMethod
I've once read that Unit Test should test the class public interface, and not the protected/private stuff.
Your class should just behave right from outside. If implementation strategy changes, your Unit Test class is still the same.