Accessing protected variable in googletest - c++

I have this class testC that is meant for google testing
class testC : public A { };
and then bunch of TEST's that are in the same file.
TEST(test_case_name, test_name) {
... test body ...
}
A is structured like this
class A{
protected:
B b;
public:
//constructors
//destructor
//member functions
Q: How can I access b in all the TEST(){} functions through testC?
I tried to do a getter in testC
public:
testC getTest(){
testC test;
return test;
}
and i also tried with returning a reference, but no luck...

Try the FRIEND_TEST macro provided by googletest. Have a look in the advanced guide under Private class members.
You have to declare the test as a friend of the code under test. If I'm not mistaken you have to declare the friendship for all tests that want to access protected members.
class MySystemUnderTest
{
#ifdef _MY_UNIT_TEST
FRIEND_TEST(MySystemUnderTest_test, functionA_prereq_expected);
FRIEND_TEST(MySystemUnderTest_test, functionB_prereq_expected);
#endif
...
};
In the example above I use the preprocessor symbol _MY_UNIT_TEST to remove the declaration from productive code. The methods functionA_prereq_expected and functionB_prereq_expected would be defined in the test fixture MySystemUnderTest_test.
You have to add the FRIEND_TEST declaration in the code under test. That's the price you have to pay if you want to test against protected / private members.

Instead of adding the FRIEND_TEST directly into the class to be tested ClassToTest surrounded by an #ifdef statement (as suggested by the post by anhoppe) for protected members and methods I would create another class test::ClassToTest which inherits from the class to be tested and registers the test suite and the tests as friends as follows:
Inside file implementation.hpp:
namespace some {
namespace complicated {
namespace ns {
// Class that we want to test
class ClassToTest {
public:
constexpr ClassToTest() noexcept
: member_to_be_accessed{7} {
return;
}
protected:
// The protected member (or method) to be accessed
int member_to_be_accessed;
};
}
}
}
Inside the file test.hpp:
#include <gtest/gtest.h>
#include "implementation.hpp"
namespace test {
// The derived class that registers the test fixture and tests as friends
class ClassToTest : public some::complicated::ns::ClassToTest {
using some::complicated::ns::ClassToTest::ClassToTest;
friend class SomeTestFixture;
FRIEND_TEST(SomeTestFixture, someTest);
};
// The test fixture
class SomeTestFixture : public testing::Test {
protected:
SomeTestFixture() noexcept
: class_to_test{} {
return;
}
ClassToTest class_to_test;
};
// A test
TEST_F(SomeTestFixture, someTest) {
EXPECT_EQ(class_to_test.member_to_be_accessed, 7);
}
}
The advantage of this is that you clearly separate the test from the implementation and that you can get around the restriction regarding namespaces:
If the class is defined in a namespace, then in order to be friends of
the class, test fixtures and tests must be defined in the exact same
namespace, without inline or anonymous namespaces.
Furthermore, as pointed out in "Testing Private Code" section of the "Advanced GoogleTest Guide" generally the black-box approach should be used: Code should be tested through its public interface only. If you can, re-structure your code separating the interface from the implementation using the Pointer to Implementation (PImpl) design strategy and test the internals independently.

Related

Injecting a Mock using registerConstructor

I've successfully set up a Mock for injection via fruit using .replace(get*Component).with(getMock*Component) like so:
#include <gmock/gmock.h>
#include "mockBar.h"
#include "classUnderTest.h"
namespace foo {
fruit::Component<ClassUnderTest, MockBar> getMainComponent()
{
return fruit::createComponent()
.replace(getBarComponent)
.with(getMockBarComponent)
.install(getClassUnderTestComponent);
}
class ClassUnderTestTest : public ::Testing::Test
{
protected:
fruit::Injector<ClassUnderTest, MockBar> injector{getMainComponent};
MockBar *mockBar{injector};
ClassUnderTest *classUnderTest{injector};
};
// TEST_F declarations
}
For the base mock as I'm writing that myself I have no problems because I can utilise the INJECT() macro on the default constructor and bind the mock to the interface in getMock*Component like so:
#include "bar.h"
namespace foo
{
class MockBar : public Bar
{
public:
INJECT(MockBar()) = default;
// MOCK_METHOD declarations
};
fruit::Component<Bar> getMockBarComponent()
{
return fruit::createComponent()
.bind<Bar, MockBar>();
}
}
For a StrictMock where the constructor is defined in the googlemock library as I understand things I should be using .registerConstructor<StrictMock<Mock*>()>() instead and this is where my problems start.
No explicit binding nor C::Inject definition was found for T.
For the sake of troubleshooting I've removed the INJECT() macro and applied this logic to the base mock like so which gives me the same error when trying to build:
#include "bar.h"
namespace foo
{
class MockBar : public Bar
{
public:
// MOCK_METHOD declarations
};
fruit::Component<Bar> getMockBarComponent()
{
return fruit::createComponent()
.registerConstructor<MockBar()>()
.bind<Bar, MockBar>();
}
}
Tried with registerProvider() like so for the sake of argument but got the same error:
fruit::Component<Bar> getMockBarComponent()
{
return fruit::createComponent()
.registerProvider([](){ return new MockBar; })
.bind<Bar, MockBar>();
}
registerFactory<Mock*()>() would appear to be excessive for what I'm trying to do (I only need the one instance) so I've not tried delving into that.
My presumption because I'm new to both googlemock and fruit and because my C++ experience isn't stellar is there's a nuance I'm missing here regardless of what I've read to the contrary.
Any ideas/suggestions for what I should try next or blaringly obvious errors I've made?
I can abstract out some more of my code if I haven't captured everything of importance here.
Ta in advance!

Google-Mock an already declared method

The syntax of MOCK_METHOD can be used inside a class definition:
class A {
MOCK_METHOD0(f, void(void));
};
Is it possible to mock a method that has already been declared? What I want is to do something similar to:
#include "gmock/gmock.h"
class HelloTest {
void f();
};
MOCK_METHOD0(HelloTest::f, void(void));
The idea is to put the class definition in an hpp file and then the mocks in a cpp file. In effect, my class definition with its methods' prototypes needs to be in common with other cpp files in my build chain and I don't want to use virtual functions.
Unfortunately, when I try to do what I wrote above, I get the following error on the line that contains MOCK_METHOD0:
error: ‘gmock0_HelloTest’ has not been declared
What does this error mean and is there a way to do what I want?
To begin with, your MOCK_METHOD0() declaration must belong to a mock class, under a public section. For instance, your code snippet:
#include "gmock/gmock.h"
class HelloTest {
void f();
};
MOCK_METHOD0(HelloTest::f, void(void));
Should instead look like this:
#include "gmock/gmock.h"
class HelloTest {
virtual void f();
};
class Mock_HelloTest : public HelloTest {
public:
MOCK_METHOD0(f, void(void));
};
Now, you'll notice that I've changed f() to be virtual instead, since your use of HelloTest::f in MOCK_METHOD0 requires f() to be virtual.
Since you don't want to use virtual functions, your only other option is to use what the Google Mock team calls hi-perf dependency injection. With this non-virtual approach, you'd have to create a separate mock class that doesn't inherit from HelloTest. You'd also need to templatize any code that currently uses HelloTest to switch between HelloTest in production and Mock_HelloTest in tests.
As an example, let's say you have the following function that calls HelloTest::f():
void RunHelloTest() {
HelloTest HT;
HT.f();
}
You would set up your code snippet as follows:
#include "gmock/gmock.h"
class HelloTest {
void f(); // <- f is no longer virtual
};
class Mock_HelloTest { // <- Mock_HelloTest no longer inherits from HelloTest
public:
MOCK_METHOD0(f, void(void));
};
And modify RunHelloTest() to accept a template type argument:
template <class HelloTestClass>
void RunHelloTest() {
HelloTestClass HT;
HT.f(); // <- will call HelloTest::f() or Mock_HelloTest::f()
}
With this setup, you'd call RunHelloTest<HelloTest>() in your production code, and RunHelloTest<Mock_HelloTest>() in your test code.

How to Mock Member Objects in C++

I want to create a unit test environment for our project. But I am lost about how to create mocks for members of the classes. I want to explain my question with an example.
In my older projects, we were using a mock selection mechanism which is very ugly in my opinion. Here is the elder method:
class member {
};
class member_mock_1 {
};
class member_mock_2 {
};
class parent {
#if defined UNIT_TEST_1
typedef member_t member_mock_1;
#elif defined UNIT_TEST_2
typedef member_t member_mock_2;
#else
typedef member_t member;
#endif
private:
member_t mem;
};
The first question is mocking the classes of the member object with typedefing in or out of the parent class is a proper way or not? What is the best practice? If I want to use a unit testing framework, like gtest, should I use this kind of way or is there another way to mocking members?
Note 1: If the virtual mechanism is activated, it is ok to create base classes to ease mocking, if a class is pod or something, I don't want to use this mechanism.
Note 2: I also find ugly passing the types of members as a template parameter, everything becomes template in the project. I don't want to do that. Here is an example:
template <typename M>
class parent {
private:
M mem;
};
#if defined UNIT_TEST_1
typedef parent_t parent<member_mock_1>;
#elif defined UNIT_TEST_2
typedef parent_t parent<member_mock_2>;
#else
typedef parent_t parent<member>;
#endif
Here is the method i am suggesting here:
member_mock_1.hpp
class member_mock_1 {
};
member_mock_2.hpp
class member_mock_2 {
};
mock.hpp
template <typename TYPE>
struct mock { using type = TYPE; };
#define ENABLE_MOCKING(NamE) \
using NamE ## _t = mock<NamE>::type
member_mock.hpp
#if define UNIT_TEST_1
template<>
struct mock<member> { using type = member_mock_1 };
#endif
#if define UNIT_TEST_2
template<>
struct mock<member> { using type = member_mock_2 };
#endif
member.hpp
class member {
};
ENABLE_MOCKING(member);
parent.hpp
class parent {
private:
member_t mem;
};
Method I have mentioned above works for normal classes. For template classes some extra works should be done, i think.
So as a conclusion, I am suggesting a structure for unit testing like above. May be it is unnecessary, there are some other mechanisms or ways to cover that requirement. Maybe I still reinventing the wheel :(
Please suggest a way you know for mocking members of a class.
Thanks.
Yes, You're reinventing the wheel the code looks really messy:
#if defined UNIT_TEST_1
typedef parent_t parent<member_mock_1>;
#elif defined UNIT_TEST_2
typedef parent_t parent<member_mock_2>;
#else
typedef parent_t parent<member>;
#endif
There are several tools available.
I use Typemock Isolator++ as you can mock pretty much everything without touching your production whatsoever.
One other thing, the behavior you set on a mock will be applied only in the scope of the test, so every test has an individual and independent setup.
You can access the member, even if it's private:
member* mock_member = FAKE<member>;
parent* my_parent = new parent();
ISOLATOR_SET_MEMBER(my_parent, mem, mock_member);
And easily get it:
member* get_member;
ISOLATOR_GET_MEMBER(my_parent, mem, get_member);
Also, it allows to fake abstract classes, global methods, pure virtual methods, private and protected methods, set up behaviors for it. Furthermore, access hidden data members and invoke them. Check this for more information.
I am in a similar situation to you - introducing unit tests to a legacy C++ project. To do so I have used a lot of preprocessor directives along with Google Test and Google Mock. Particularly, if I was facing to your example, I would do as follows:
#if defined UNIT_TEST
class imember
{
virtual void a_method() = 0;
};
#endif
class member
#if defined UNIT_TEST
: public imember
#endif
{
void a_method()
{
// do something
};
};
class parent {
public:
#if defined UNIT_TEST
parent(imember mem) : mem_(mem) {};
#endif
private:
#if defined UNIT_TEST
imember mem_;
#else
member mem_;
#endif
};
Now, use Google Mock to define a mock class:
class mockmember : public imember
{
public:
MOCK_METHOD0(a_method, void());
};
Mock class is now ready. Use Google Test to define your test scenarios:
class parenttest : public testing::Test
{
public:
parenttest() : member_(mockmember()), parent_(member_) {}
virtual void SetUp() {}
virtual void TearDown() {}
protected:
parent parent_;
mockmember member_;
};
TEST_F(parenttest, a_func)
{
EXPECT_CALL(member_, a_method());
int ret = parent_.a_func();
ASSERT_EQ(0, ret);
}
Disclaimer, i work in Typemock.
Sam is totally right.
Also, you don't need to create 3 different member_mock classes for every single unit-test.
You can simply set up the behavior, for example, for some private method in member:
member* mock_member = FAKE<member>;
PRIVATE_WHEN_CALLED(member, somePrivateMethod()).Return(0);
Next using PRIVATE_WHEN_CALLED(mock_member, somePrivateMethod()) will overload behavior for somePrivateMethod(), so, instead of creating huge amount of different mock-classes just change the behavior for you needs.
Hope it'll be useful for you!

Namespace-level access

I have the following situation:
namespace MyFramework {
class A {
void some_function_I_want_B_to_use() {}
};
class B {
B() {
some_function_I_want_B_to_use() {}
}
};
}
where I want the some_function_I_want_B_to_use to not be visible outside of the MyFramework namespace, but I do want it to be visible to anyone inside of MyFramework (alternatively, visible to just class B is also ok). I've got a number of methods like this, is the only way to hide them from the public API of MyFramework to make all classes within MyFramework friends? I was also considering placing all "lower-level" classes inside of B, but I don't want to go down that route until I'm sure it would accomplish the ability to access all of A's methods from inside of B but not from outside of MyFramework.
To restate, I've got a framework that's all created within one namespace, and each class has methods that are useful to the general public using the framework. However, each class also has a few methods that complicate the public API but are needed for the framework to function properly.
I want the some_function_I_want_B_to_use to not be visible outside of the MyFramework namespace, but I do want it to be visible to anyone inside of MyFramework.
In summary, you want something similar to packages in Java.
Unfornately for you, that is not possible with namespaces. Every class included in a namespace is accessible from the outer of the namespace: namespaces are open.
The solution is usually to add another namespace for implementation details:
namespace MyFramework
{
// Implementation details
// Should not be used by the user
namespace detail
{
class A
{
public:
void func();
};
}
class B
{
public:
B()
{
A a;
a.func();
}
};
}
Don't forget to add a comment stating the detail namespace is not to be used by user.
Pimpl idiom, frequently called Compilation Firewall, is what you are looking for. The whole Qt is implemented using this idiom.
// A.hpp
namespace MyFramework {
class A {
private:
class Private;
Private* implementation;
};
}
// A_Private.hpp
#include "A.hpp"
namespace MyFramework {
class A::Private {
public:
void some_function_I_want_B_to_use() {}
};
}
// A.cpp
#include "A_Private.hpp"
namespace MyFramework {
A::A() {
implementation->some_function_I_want_B_to_use();
}
}
// B.hpp
#include "A.hpp"
namespace MyFramework {
class B {
B();
A a;
};
}
// B.cpp
#include "A_Private.hpp"
namespace MyFramework {
B::B() {
a.implementation->some_function_I_want_B_to_use();
}
}
NOTE: Of course A_Private.hpp does not go into the include directory of you framework final distribution, i.e. it remains package private as you require.
The example is very basic. Of course it can be made more advanced and robust. Additionally, Pimpl has lots of other advantages. For all this information refer to:
GotW #100: Compilation Firewalls (Difficulty: 6/10)
GotW #101: Compilation Firewalls, Part 2 (Difficulty: 8/10)
Pimp My Pimpl — Reloaded
Pimp My Pimpl
Dpointer
The common convention, e.g. in Boost, is a nested namespace called detail.
If you want to enforce the accessibility you can always instead use a nested class called detail. The class provides accessibility checking, but lacks extensibility like a namespace. However, a detail scope will rarely if ever need extension.
So, in all its ugliness,
namespace my_framework {
class detail
{
private:
static void some_function_I_want_B_to_use() {}
public:
class A
{};
class B
{
B() { some_function_I_want_B_to_use(); }
};
};
typedef detail::A A; // "using detail::A"
typedef detail::B B; // "using detail::B"
} // namespace my_framework
In passing, note that class B (straight from the question) has a private default constructor so no instances of it can be created.

How can I test private members and methods of classes?

I am trying to do unit testing (using the Boost unit testing framework) on a C++ class called VariableImpl. Here are the details.
class Variable
{
public:
void UpdateStatistics (void) {
// compute mean based on m_val and update m_mean;
OtherClass::SendData (m_mean);
m_val.clear ();
}
virtual void RecordData (double) = 0;
protected:
std::vector<double> m_val;
private:
double m_mean;
};
class VariableImpl : public Variable
{
public:
virtual void RecordData (double d) {
// Put data in m_val
}
};
How can I check that the mean is computed correctly? Note that 1) m_mean is protected and 2) UpdateStatistics calls a method of another class and then clears the vector.
The only way I can see would be to add a getter (for instance, GetMean), but I don't like this solution at all, nor I think it is the most elegant.
How should I do?
And what should I do if I were to test a private method instead of a private variable?
Well, unit testing should test units and ideally every class is a self-contained unit – this follows directly from the single responsibility principle.
So testing private members of a class shouldn’t be necessary – the class is a black box that can be covered in a unit test as-is.
On the other hand, this isn’t always true, and sometimes with good reasons (for instance, several methods of the class could rely on a private utility function that should be tested). One very simple, very crufty but ultimately successful solution is to put the following into your unit-test file, before including the header that defines your class:
#define private public
Of course, this destroys encapsulation and is evil. But for testing, it serves the purpose.
For a protected method/variable, inherit a Test class from the class and do your testing.
For a private, introduce a friend class. It isn't the best of solutions, but it can do the work for you.
Or this hack:
#define private public
In general, I agree with what others have said on here - only the public interface should be unit tested.
Nevertheless, I've just had a case where I had to call a protected method first, to prepare for a specific test case. I first tried the #define protected public approach mentioned above; this worked with Linux/GCC, but failed with Windows and Visual Studio.
The reason was that changing protected to public also changed the mangled symbol name and thus gave me linker errors: the library provided a protected __declspec(dllexport) void Foo::bar() method, but with the #define in place, my test program expected a public __declspec(dllimport) void Foo::bar() method which gave me an unresolved symbol error.
For this reason, I switched to a friend based solution, doing the following in my class header:
// This goes in Foo.h
namespace unit_test { // Name this anything you like
struct FooTester; // Forward declaration for befriending
}
// Class to be tested
class Foo
{
...
private:
bool somePrivateMethod(int bar);
// Unit test access
friend struct ::unit_test::FooTester;
};
And in my actual test case, I did this:
#include <Foo.h>
#include <boost/test/unit_test.hpp>
namespace unit_test {
// Static wrappers for private/protected methods
struct FooTester
{
static bool somePrivateMethod(Foo& foo, int bar)
{
return foo.somePrivateMethod(bar);
}
};
}
BOOST_AUTO_TEST_SUITE(FooTest);
BOOST_AUTO_TEST_CASE(TestSomePrivateMethod)
{
// Just a silly example
Foo foo;
BOOST_CHECK_EQUAL(unit_test::FooTester::somePrivateMethod(foo, 42), true);
}
BOOST_AUTO_TEST_SUITE_END();
This works with Linux/GCC as well as Windows and Visual Studio.
A good approach to test the protected data in C++ is the assignment of a friend proxy class:
#define FRIEND_TEST(test_case_name, test_name)\
friend class test_case_name##_##test_name##_Test
class MyClass
{
private:
int MyMethod();
FRIEND_TEST(MyClassTest, MyMethod);
};
class MyClassTest : public testing::Test
{
public:
// ...
void Test1()
{
MyClass obj1;
ASSERT_TRUE(obj1.MyMethod() == 0);
}
void Test2()
{
ASSERT_TRUE(obj2.MyMethod() == 0);
}
MyClass obj2;
};
TEST_F(MyClassTest, PrivateTests)
{
Test1();
Test2();
}
See more Google Test (gtest).
Unit test VariableImpl such that if its behavior is ensured, so is Variable.
Testing internals isn't the worst thing in the world, but the goal is that they can be anything as long as the interfaces contracts are ensured. If that means creating a bunch of weird mock implementations to test Variable, then that is reasonable.
If that seems like a lot, consider that implementation inheritance doesn't create great separation of concerns. If it is hard to unit test, then that is a pretty obvious code smell for me.
While in my opinion the need of testing private members/methods of a class is a code smell, I think that is technically feasible in C++.
As an example, suppose you have a Dog class with private members/methods except for the public constructor:
#include <iostream>
#include <string>
using namespace std;
class Dog {
public:
Dog(string name) { this->name = name; };
private:
string name;
string bark() { return name + ": Woof!"; };
static string Species;
static int Legs() { return 4; };
};
string Dog::Species = "Canis familiaris";
Now for some reason you would like to test the private ones. You could use privablic to achieve that.
Include a header named privablic.h along with the desired implementation like that:
#include "privablic.h"
#include "dog.hpp"
then map some stubs according to types of any instance member
struct Dog_name { typedef string (Dog::*type); };
template class private_member<Dog_name, &Dog::name>;
...and instance method;
struct Dog_bark { typedef string (Dog::*type)(); };
template class private_method<Dog_bark, &Dog::bark>;
do the same with all static instance members
struct Dog_Species { typedef string *type; };
template class private_member<Dog_Species, &Dog::Species>;
...and static instance methods.
struct Dog_Legs { typedef int (*type)(); };
template class private_method<Dog_Legs, &Dog::Legs>;
Now you can test them all:
#include <assert.h>
int main()
{
string name = "Fido";
Dog fido = Dog(name);
string fido_name = fido.*member<Dog_name>::value;
assert (fido_name == name);
string fido_bark = (&fido->*func<Dog_bark>::ptr)();
string bark = "Fido: Woof!";
assert( fido_bark == bark);
string fido_species = *member<Dog_Species>::value;
string species = "Canis familiaris";
assert(fido_species == species);
int fido_legs = (*func<Dog_Legs>::ptr)();
int legs = 4;
assert(fido_legs == legs);
printf("all assertions passed\n");
};
Output:
$ ./main
all assertions passed
You can look at the sources of test_dog.cpp and dog.hpp.
DISCLAIMER: Thanks to insights of other clever people, I have assembled the aforementioned "library" able to access to private members and methods of a given C++ class without altering its definition or behaviour. In order to make it work it's (obviously) required to know and include the implementation of the class.
NOTE: I revised the content of this answer in order to follow directives suggested by reviewers.
I generally suggest testing the public interface of your classes, not the private/protected implementations. In this case, if it can't be observed from the outside world by a public method, then the unit test may not need to test it.
If the functionality requires a child class, either unit test the real derived class OR create your own test derived class that has an appropriate implementation.
Example from the Google testing framework:
// foo.h
#include "gtest/gtest_prod.h"
class Foo {
...
private:
FRIEND_TEST(FooTest, BarReturnsZeroOnNull);
int Bar(void* x);
};
// foo_test.cc
...
TEST(FooTest, BarReturnsZeroOnNull) {
Foo foo;
EXPECT_EQ(0, foo.Bar(NULL));
// Uses Foo's private member Bar().
}
The main idea is the use of the friend C++ keyword.
You can extend this example as follows:
// foo.h
#ifdef TEST_FOO
#include "gtest/gtest_prod.h"
#endif
class Foo {
...
private:
#ifdef TEST_FOO
FRIEND_TEST(FooTest, BarReturnsZeroOnNull);
#endif
int Bar(void* x);
};
You can define the TEST_FOO preprocessor symbol in two ways:
within the CMakeLists.txt file
option(TEST "Run test ?" ON)
if (TEST)
add_definitions(-DTEST_FOO)
endif()
as arguments to your compiler
g++ -D TEST $your_args