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

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.

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() {}
}

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

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.

Create extended anonymous class for Abstract class in TypeScript

I have abstract class which has few implemented protected methods and few abstract methods.
I am trying to write some tests for the protected methods.
Since these are not available even in the extended classes to outside world, I would like to create anonymous Test class which can extend and verify/mock my stuff.
export abstract class AbsClass implements AbsInterface {
protected extract(filter: string) {
//some implemented code to test
}
abstract someMethod();
}
I am not able to figure out how to create something like this anonymously
export class TestClass extends AbsClass {
public testExtract(){
//call super.extract and verify result
}
}
I've run into this before. It seems like the export/abstract keywords interfere with each other. I've had to define the class and then export on a separate line to get around this.
Example:
abstract class BaseClass {}
export default BaseClass
There are some workarounds discussed in this related issue. See also:
https://github.com/microsoft/TypeScript/issues/36060
https://github.com/microsoft/TypeScript/issues/17293
https://github.com/microsoft/TypeScript/issues/35822
The short answer is that it's very difficult to represent anonymous classes that access private/protected members of their superclass right now. If you're just trying to test parts of the superclass, does the implementing class really have to be anonymous?
(As an aside: I'm still pretty new at testing generally, but I've seen a lot of strongly worded advice about not explicitly testing private/protected methods. Would it be preferable to test the public API methods that call the private/protected ones instead?)

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.

How to use inheritance for a class with TEST_CLASS in CppUnitTestFramework

I've got a class that inherits from another class like so:
class TestClass : public BaseClass
I am wondering if it is possible to make this a test class using the TEST_CLASS macro or some other macro that is part of the Microsoft Unit Testing Framework for C++. I tried:
class TEST_CLASS(TestClass : public BaseClass)
But the IDE gives the error 'Error: expected either a definition or a tag name' and the compiler error is error C3861: '__GetTestClassInfo': identifier not found
I know it's probably bad practice to inherit on a test class but it would make implementing the test easier. I am relatively new to C++ so I am wondering if it is something simple I have missed or if it's just not possible.
Thanks,
There is one other option you didn't include and others may be tripping over this question without knowing the solution.
You can actually derive from any arbitrary type by looking at the macro itself:
///////////////////////////////////////////////////////////////////////////////////////////
// Macro to define your test class.
// Note that you can only define your test class at namespace scope,
// otherwise the compiler will raise an error.
#define TEST_CLASS(className) \
ONLY_USED_AT_NAMESPACE_SCOPE class className : public ::Microsoft::VisualStudio::CppUnitTestFramework::TestClass<className>
As C++ supports multiple inheritance you can easily derive by using code similar to the following:
class ParentClass
{
public:
ParentClass();
virtual ~ParentClass();
};
TEST_CLASS(MyTestClass), public ParentClass
{
};
Just remember that if you are working with resources you will need to have a virtual destructor to have it be called. You will also have to call the initialize & cleanup methods directly if you are going to be using them, because the static methods they create are not called automagically.
Good luck, Good testing!
It's been a while since I used CppUnitTestFramework but back then this site has been a valuable resource for many questions on that topic.
TEST_CLASS is preprocessor macro. You can use it to declare a test class like
TEST_CLASS(className)
{
TEST_METHOD(methodName)
{
// test method body
}
// and so on
}
That's it. As far as I know there is no way to inherit test classes from one another.
Maybe though composition over inheritance might help in your specific case.