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
Related
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
We may declare a final/sealed non-inheritable class using the new C++ keyword final.
class Generator final
{
};
This class may inherit from other, may or may not have virtual (inherited or not). But, how to make it final, yet allow one class to inherit from it?
We mostly need to derive a mock class from real class (with or without late-binding, hence virtual isn't important). How to make it work:
class MockGenerator : Generator{};
But disallow any other inheritance?
But, how to make it final, yet allow one class to inherit from it?
That's not possible.
We mostly need to derive a mock class from real class (with or without late-binding, hence virtual isn't important).
If the class is final, you do not need to derive from it. If you do need to derive from it, it is not final. Pick one.
Edit: You can add restrictions to your class, but those come at their own cost to the interface:
class Generator // not final
{
Generator(); // the only accessible constructor is private
// whitelist who has access to this constructor
friend class MockGenerator;
public:
// no public constructors here except for copy & move
Generator(Generator&);
Generator(Generator&&);
...
// provide controlled access to the private constructor
static Generator make_generator() { return Generator(); }
// rest of API here
};
This is a class that allows it's factory and MockGenerator specializations to call it's constructor. This comes at the price of blocking trivial construction though.
Old code (no longer compilable):
Generator instance;
New code (enforced by the private constructor):
auto instance = Generator::make_generator();
One possibility: use a define for final and define it as empty when generating the test environment.
#ifdef MOCK
#define CLASS_FINAL
#else
#define CLASS_FINAL final
#endif
edit: I agree with the comment of utnapistim: this is not a recommendation, just a technical possibility (but at least better than #define final).
If you need to create mock class it for unit-testing, then you can try Typemock Isolator++. Because it easily handles with final classes. You don't even need to change something in you production code (like creation of separate mock class). I've created simple test to demonstrate it:
class Generator final
{
public:
int foo()
{
return 0;
}
};
TEST_METHOD(TestFinal)
{
Generator* generator = FAKE<Generator>();
WHEN_CALLED(generator->foo()).Return(1);
int result = generator->foo();
Assert::AreEqual(1, result);
}
Hope it can be useful for you.
This question already has answers here:
Unit testing accessors (getters and setters)
(3 answers)
Closed 8 years ago.
Are there best practices for testing classes that use inheritance?
For example if I have a class BaseNode
public class BaseNode
{
int testInt;//attribute
//assume getters and setters and constructor
public function somethingComplicated()
{
//put complex code here
}
}
and another class called InputNode that inherits from BaseNode.
public class InputNode extends BaseNode
{
int secondTest;//attribute
//assume getters and setters and constructor
}
If I write getters and setters for both classes, what would I need to test?
Do you really have to write tests for getTestInt() in both the BaseNode and the InputNode classes?
If you write a test for getTestInt() in the InputNode class does that automatically count as a test for the BaseNode class as well?
Edited question to make it more specific. I'm not just asking about getters and setters.
If you write a test for somethingComplicated() in the Base class do you automatically assume that the test is valid for the InputNode class?
I originally used getters and setters as a simple example to try and illustrate the concept. I didn't mean that I only wanted to test the getters and setters.
First of all, setters are a code smell, in no small part because they increase the complexity of testing. They do this because they potentially increase number of possible states an object can be in.
The best practices are:
Minimize setters
Every derived object has to pass every base class test, so make sure you set your tests up to do just that. If they don't pass, then that means that base instances are not liskov substitutable. The upside of this is that you shouldn't need to write a complete set of new tests for every derived class.
You'll need tests to specifically ensure that your new setters and behaviours don't interact incorrectly with base class behaviour.
The full suite of tests for the base class needs to pass for each derived class in order to demonstrate Liskov substitutability. In addition, tests for the specialization provided by the derived class need to exist. Many folks choose to organize the test classes in a way that mirrors the classes under test for just this reason.
Given a class InputNode that subclasses BaseNode, we might have test classes that look like this
[corrections to my Java syntax are welcome]:
public class BaseNodeTest {
protected BaseNode getBaseNode () {
return new BaseNode();
}
public void test_complicated_BaseNode_behavior () {
BaseNode bn = getBaseNode();
// actual test code...
}
}
public class InputNodeTest extends BaseNodeTest {
protected BaseNode getBaseNode () {
return new InputNode();
}
public void test_InputNode_specific_behavior () {
InputNode in = getBaseNode();
// actual test code...
}
}
The key point is that InputNodeTest will run all of the tests in BaseNodeTest against InputNode and add its own tests. This assures that InputNode could be used wherever a BaseNode is expected.
You have to test the base class too, because the base node's method/getter could be affected by code in the base class that is:
overriden by derived classes
code in derived classes may cause side effects (by changing base class fields, etc.)
Is it possible to unit test a private class? I have something like
public class ClassA: ClassB
{
private class ClassX: ClassY
{
public static int TestMethod(int numberA, int numberB)
{
return numberA + numberB
}
}
}
I'd like to test the "TestMethod" but can't access it. I tried to create new instance for the private ClassX using Class A and Class Y but it won't let me access the "TestMethod"
It is not a good practice to test private members. They should be tested using pubic exposed members.
However, If you are using MSTest, You can use accessors.
If you are using other test frameworks, you can leverage reflection.
The above are applicable in .NET. I have no idea how to achieve the same in other languages (in case you are asking for java/other language).
There should be a public method somewhere that calls the method in your private class. You should unit test that method. If you can't get to your private method through a public interface, then there is probably no need for the private method to begin with.
I've never developed using Test Driven Development, and I've never used Mock Objects for unit testing. I've always unit tested simple objects that don't incorporate other aspects of the application, and then moved on to less simple objects that only reference objects that have already been unit tested. This tends to progress until the final "unit" test is a component test.
What design techniques are used to make the replacing of internal classes with Mock Objects as easy as possible?
For example, in my code, I would include the header file for myDataClass within myWorkerClass. myDataClass is constructed by myWorkerClass, and its lifetime is tied to myWorkerClass. How can you set it up so that it would include a mock myDataClass when the include is hard-wired?
A beginners answer would be:
in tested class don't use the actual
type of mocked one, use its
interface
while testing provide
another realization of mocked object
interface
//Common header
class ObjectInterface {
public:
virtual void doThings()=0;
};
//Release
class RealObject: public ObjectInterface {
public:
virtual void doThings(){
//Complicated work here
}
};
//Testing
class MockedObject: public ObjectInterface {
public:
virtual void doThings(){
//Not so complicated work here
}
};
//Common header
class TestedClass {
public:
void useObject(ObjectInterface & object) {
object->doThings();
}
};
//Unit test
TestedClass toTest;
MockedObject mockedObject;
toTest.useObject(mockedObject);
You could look to adapt your code to follow an (Abstract) Factory Design pattern, whereby a different factory could be used in a unit test environment that would create your mock objects.
One way would be to not hard-wire your classes like that.
Using your example:
myDataClass would be a pure virtual class. This would have at least 2 implementations, the 'real' one and the mock.
Your test code could inject a mock instance by having 2 constructors, one that takes a 'myDataClass' and one that doesn't. See the code below for an example.
class myWorkerClass {
public:
myWorkerClass(myDataClass * dc) : m_dc(dc) {}
myWorkerClass() : m_dc(new MyRealDataClass()) { }
~myWorkerClass { delete m_dc; }
private:
myDataClass *m_dc;
}
Now, you can provide any implementation of the myDataClass to the myWorkerClass you want. If you don't provide an implementation, then your code falls back on the 'real' implementation.
Another technique would be to use the Factory pattern to instantiate your objects. Your test code could set some flag on the factory that creates instances of myDataClass and have it produce a mock object instead of the real one. I prefer the first technique as to me it's a little easier to use (plus I don't have to maintain a factory class for everything I want to test)