Using friendship in test - c++

I'm looking for a "clean" way of accessing some private member variables in a test context without touching the original code. I was thinking about implementing a friendship relation with the test class, but for some reason I do not understand it still requires a protected accessor in order to work. Why is it like that? Is there any other way to access the private member variable?
class A
{
protected: // this works
// private: // this DOES not work
int a;
};
class TestableA : public A
{
friend class TestA;
};
class TestA
{
void test()
{
m_a.a = 100;
}
TestableA m_a;
};

You can't access a private variable from a derived class, only protecteds.
TestA is a friend of TestableA, so it can see everything TestableA contains. But if a is private, you can't access it in TestableA.
You have several options:
use protected everywhere
add the friend declarations to class A directly. You can even do it with a macro, which only effects the debug/test build.
For more information about this topic, there's a good presentation called Friendship in Service of Testing

Related

force a specific constructor used solely in certain code, nowhere else

Sometimes, we need to provide a specific constructor solely for test usage. How can we force such constructor is solely used in test code, nowhere else.
I just wonder if this is achievable in c++11/14. e.g.,
class A {
public:
A() = default; // used only in test code
}
class A_Test : public ::testing::Test {
private:
A a; // it is ok.
};
class A_Production {
private:
A a; // compiler error
}
I could imagine to use friend decorator and put the specific constructor in protected to limit the access. but there are other existing friends in legacy code too. Is it possible to make a custom specifier like protected in c++1x?
any ideas?
You could use the Passkey Idiom:
Instead of a direct friendship, you limit the access to A from A_Test through the indirection provided by ConstructorKey, which A uses in its interface where it wants the friends of ConstructorKey to access.
class A {
class ConstructorKey {
friend class A_Test;
private:
ConstructorKey() {};
ConstructorKey(ConstructorKey const&) = default;
};
public:
// Whoever can provide a key has access:
explicit A(ConstructorKey); // Used only in test code
};
class A_Test : public ::testing::Test {
private:
A a {ConstructorKey{}}; // OK
};
class A_Production {
private:
A a {ConstructorKey{}}; // Compiler error
};
I can think of several ways to do that.
Make the constructor protected, with only the test subclass using it.
Add a forward declaration to some dummy class, class TestClassThatShouldNotBeUsedInProductionCode;, then declare a constructor that takes a reference to this class as a parameter:
A::A( /* other constructor arguments */,
const TestClassThatShouldNotBeUsedInProductionCode &)
This constructor can simply ignore this parameter altogether. Your test module can define this dummy, empty class: class TestClassThatShouldNotBeUsedInProductionCode {};, and be able to construct your A class using it. Only your test module would be able to use this constructor, then, and its name makes it pretty clear what the purpose of this is. There isn't really any way to define certain translation units as "real" code versus "test" code, in C++, you just want to implement a clear policy that would be hard to violate accidentally.
Some variations are possible, such as using an inner class instead of forward-declaring a standalone class. The inner class could only be instantiated only by the test code.
As an alternative, in the cpp file that does the testing of A:
#define private public
#include "ClassA.h"
// ready for testing :)

Hide class members outside namespace

I have a collection of classes that have node like relationships. Due to this, I need to access some of the parents/chilren functions that I'd otherwise like to keep away from the end user since they just clutter the suggested method list, make no sense and break things really bad when used from outside their own "ecosystem".
I figured if they'd all inherit the same base class with virtual placeholder functions then I could access the protected members but apparently not. Is there a way to hide class members from access outside a certain namespace or a container class while being accessible from within?
If you really have to has access to some protected/private data you can make friend classes.
From Wikipedia:
class B {
friend class A; // A is a friend of B
private:
int i;
};
class A {
public:
A(B& b) {
b.i = 0; // legal access due to friendship
}
};

Accessing private C++ methods within C++/CLI wrapper

Given a class method in C++ that has to be private there, how to make C++/CLI access it. Example: C++ class has a private constructor that shouldn't be exposed to the external user, C++/CLI managed code has to have similar private constructor, but internally it must access private C++ constructor to instantiate a member pointer referring to C++ native class.
Keep in mind, first of all, the goal of making things inaccessible (i.e. private) generally contradicts the goal of making things accessible. If you're able to change the class declaration, then you have some options. I don't know the specifics of your C++/CLI requirements, but perhaps one of these options will give you what you need.
Protected and Inheritance
To an "outsider", private and protected members are equally inaccessible. But to a subclass, private is still private while protected members are accessible. You can gain access to protected members by subclassing. This can be one way to unit test "private" members of a class without fully exposing it to the world.
class A {
protected: // was private
int sum(int a, int b);
};
class TestA : public A {
public:
bool testSum(int expected, int a, int b) {
return expected == sum(a, b);
}
};
So access to protected method sum in class A becomes accessible by making it protected and subclassing. The private member will remain inaccessible to everything else except subclasses.
Static Factory Method
You mentioned a private constructor; if you are needing to manage construction, you might accomplish that with a static factory method. For instance:
class Foobar {
private:
Foobar() { } // Don't let anyone just make one.
public:
static Foobar* Create() { return new Foobar; }
};
// To create a Foobar instance:
Foobar* pfoo = Foobar::Create();
This is not the best interface (better to use a shared_ptr, for instance), but it demonstrates my meaning. Note that since the factory function Create is public, anyone can create one. However, you can change the body of Create to something more complex: include bookkeeping, initialization, etc. The factory method is a way to manage creation, not restrict it. Granted, you may not want this, but it's an option if you need to manage construction.
Friends
C++ permits giving access of the private parts of classes to other classes/functions via the friend keyword.
class A {
int x; //private
friend class B;
};
class B {
void foobar(A& a) {
a.x = 42; // permissible, because A declared class B a friend
}
};
Friendship can be granted to another class or to a function. This can easily break encapsulation and make code difficult to follow or keep safe, but it also gives you the means to expose private members to exactly just those who need it.

Testing protected member with googletest

I'm confused regarding inheritance when googletesting. I have a class A that has protected attributes. If I want to access those i have to extend that class, but at the same time i also need to extend public ::testing::Test for the sole purpose of gtest.
What is the most elegant solution to this problem?
Also I'm trying to avoid #define protected public
To avoid leaving traces of tests in the tested class use multiple-inheritance with a fixture:
class ToBeTested
{
protected:
bool SensitiveInternal(int p1, int p2); // Still needs testing
}
// Google-test:
class ToBeTestedFixture : public ToBeTested, public testing::Test
{
// Empty - bridge to protected members for unit-testing
}
TEST_F(ToBeTestedFixture, TestSensitive)
{
ASSERT_TRUE(SensitiveInternal(1, 1));
ASSERT_FALSE(SensitiveInternal(-1, -1));
}
There is a FRIEND_TEST declaration, which is used in the header of tested class. Basically it defines the test as a friend of the class. In my use case, we disable all test includes when compiling in RELEASE mode, so it doesn't do any harm the real executable.
Have a look at this

Inheriting friendship in C++?

Since class friendship is not inherited in C++, what's the best way to "fake" it?
I was thinking about exposing the friend class's private interface through protected methods in the to-be-inherited base-class, but that results in having to write (and maintain) the same interface twice.
Are there any other ways?
The use of a key is a possible solution.
The idea is that you can unlock the operations only if you have a key... but an example is worth thousands on word so let's dive:
// Step 1: The key
class NeedAccess;
namespace details { class Key { friend NeedAccess; Key() {} }; }
// Step 2: NeedAccess
class NeedAccess
{
protected:
static details::Key GetKey() { return details::Key(); }
};
// Step 3: The big one
class BigOne
{
public:
void lockedMethod(details::Key);
};
The matter of key being copy constructable is up to discussion. I don't see what you can gain by preventing it.
Another benefit is that you can have several keys, depending on which method you want to access, this way you grant 'partial' friendship, and your 'partial' friends can't mess around with your private parts, despite the famous claim!
EDIT:
This method is called Limited Friendship, and was discussed on comp.lang.c++.moderated.
The main advantage of this method in comparison to Private Interface, is the loose coupling, since only forward declarations are necessary.
The children of the class with frinedship need to ask there parent to do the access for them.
class CrustyNeighbour
{
private:
friend class Bob;
void useWiFi(std::string const& data);
};
class Bob
{
protected:
useWifi(CrustyNeighbour& neighbour,std::string const& data)
{ neighbour.useWiFi(data);}
};
class Mary: public Bob // Bob's offspring
{
void playHalo(WifiOwner& owner) // WifiOwner derived from CrustyNeighbour
{
useWifi(owner,gameData); // use wifi via his/her parent who access to eighbours wifi
}
};
Not sure if this isn't what you're already thinking about but here's a Virtual Friend example