Unit testing a class constructor - c++

In C++ how would one test a class constructor? For example:
Class myClass{
int a;
public:
myClass(); //Constructor
void reset(); //resets a to 0;
};
//Constructor defined to initialize a to 0
myClass::myClass(){
reset();
}
//reset sets a to 0
void myClass::reset(){
a = 0;
}
How would I test the myClass() constructor? I can't access the private data member, so would it be valid to say if reset works then the constructor works?

I am going to rephrase your question to: how do I test properties of my class that are not directly observable from my tests because they are protected or private? Here are several possibilities in the order that I usually think about them:
Move the checking part of the test into the class by using an assert(). If what you want to test is that your constructor has successfully established some complex invariant, then you can put an assert() at the end of the constructor that verifies that invariant. Then all your test has to do is to call the constructor - the assert inside the constructor does the actual checking that the test would otherwise have done. If you habitually add asserts as you write the code then that assert will already be there (if asserts make your debug build too slow, use a profiler to pinpoint those asserts that are actually a problem).
Extract the complex piece of code that you want to test into a second class. You can then test the second class through its public interface. This option is attractive when extracting the second class improves the code even when not considering testability.
Change the design of your code to something more testable in some other way. Again, this is attractive when the change is an improvement even when not considering testability.
Strategic retreat. Testing code in isolation is good all other things being equal, but there is no law saying that all code must be tested in isolation. Sometimes the right answer is to just let that code be tested as a side-effect of testing something else. All your other tests for that class will call the constructor, after all, so if something is wrong with the constructor it will probably cause one of those other tests to fail. It may be harder to cover all paths this way and at the time that you get that failure it will be more trouble to track down the cause of the failure because now you do not know if the problem is the constructor or the other thing being tested. That may or may not be a big deal. Is it truly worth the trouble to test this code in isolation, taking into consideration what else you could be using that time on and the probability that this test will ever actually find a bug? Would a code review be a more useful way to spend that time? Is there something else that it would be more useful to do?
If you truly must test something that cannot be tested with assert() and where there is no acceptable refactoring to improve testability, then there are still some options. I've never had to use these for testing, but here they are:
Use a friend declaration to give your tests access to private fields on your class. Each class now needs to maintain a list of friend declarations for tests that need access. This can be a chore to maintain.
Maintain a separate interface for use by tests. Have a set of methods that give the access that you need and whose name has a prefix like "testOnly". So in your case it would be testOnlyGetA(). You will have to be disciplined in only calling these methods from tests and you now need to maintain a larger interface than before.
Hold your nose and do #define private public in your test file before including the header that you want to test.

Upd. Sorry, misunderstood.
You may add a friend testing function to a class or a class-member testing function (which is better to test implementation details, but sometimes is impossible due to testing framework restrictions)

You could add a boost test case to the class:
Class myClass{
private:
int a;
public:
myClass(); //Constructor
void reset(); //resets a to 0;
void test_a_reset() {
BOOST_CHECK_EQUAL(a, 0);
}
};
Im not sure about how you are doing the testing though. This may not be what you want.

You can declare a test class with the same memory layout of your original class, but all members being public.
void testMyClassConstructor()
{
class myClassPublic
{
public:
int a;
myClassPublic();
void reset();
};
typedef union
{
myClass* original;
myClassPublic* testView;
} u_myClass;
myClass testInstance;
u_myClass testUnion;
testUnion.original = &testInstance;
assert(testUnion.testView->a == 0);
}
This is fine in a white box test case, if you can't change the tested class' interface.
However, remember that any changes to the memory layout of the original class will break the unit test aswell.

Related

How to test behavior based on private class using members c++ using gtest

I want to use Google test to test my class.
Lets assume I have a state machine implementation and the current state is private
so I have a method SetNextState that looks like that:
void setNextState
{
switch(m_currentState) //m_currentState is a private member
{
case INIT_STATE:
{
if some conditions occurred m_currentState=GO_STATE
}
......
}
}
so I have several cases and each define the behavior to move from certain state to another.
My question:
How do I perform tests on that method assuming the state is relevant only to this class so there is no output
How do I set its value to be, for example "GO_STATE" to test the GO_STATE case
and how do i check the m_currentState at the end of the test
Im trying to avoid putting friends etc. in my UUT code since I want it to be as original as possible
You don't. You do the same thing that your actual program will do, which is provide an input, then examine the result; you say there's no output, but there must be some effect, otherwise the class is pointless!
Failing that, you could make the test a "friend" of the class so that it can inspect its internals, or add an immutable getter for the current state (and who really cares if your class's users get to see that?) but neither option is really in the spirit of the thing.
In my experience, you'll occasionally realise that you're not really unit testing any more but instead functional testing, and Google Test may not be the right tool for that job. If your class is as big as it sounds, that could be the case here. Conversely, you could help yourself by splitting the class into smaller chunks, then unit testing those. Depends what you're going for, really.
Lightness Races in Orbit is correct. However, if sometimes you feel like it's useful to test the private member functions of your class, it often means that your class could be split in multiple smaller pieces.
If you don't think those smaller components are useful to the clients of your library, you can simply hide them in a detail:: namespace and then create unit tests as usual. This will allow you to test the internal behavior of your classes without polluting your public API.
After much considerations I decided to wrap my UUT with a helper which provides set and get to the relevant private members.and use it in the test procedure before calling the tested API
Original code
===============
class UUT //That's the actual class I want to test
{
protected:
int m_protectedMember;
public:
void methodToTest()
{
//Do something with m_protectedMember use its value as input
//and set it as output
}
};
In the tester
==============
class UUTHelper: public UUT
{
public:
int getProtectedMember() { return m_protectedMember; }
void setProtectedMember(int value) { m_protectedMember = value; }
};
The pros:
My test code is very simple and I easily create complicated scenarios .
I test the real code without any "friends" or any other manipulations.
The cons:
As written in the discussion, not the best "good practice", touching private members
Thank you all :)

Need help google testing a unique Id generator

I have a C++ class that generates unique IDs in the following fashion.
class Foo
{
static int seed;
public:
const int Uid;
Foo() : Uid(seed++) {}
}
int Foo::seed = 0;
Now I'm using Google Test to test this Id generator using:
Foo foo;
EXPECT_EQ(0, foo.Uid);
Foo foo2;
EXPECT_EQ(1, foo2.Uid);
This test passes when I debug it but fails when I actually run it, giving me IDs of 2 and 3 instead. Can someone help me figure out why? Is Google test running two of these tests back-to-back or something?
One of characteristics of good tests is repeatability with not depending on tests order execution.
You have a singleton, and you use it in a bad way. If we assume there are no memory problems, then what most likely happens, is that the object of type Foo is somewhere created, and that your tests are getting executed in different order for debug and normal runs. That would explain different results.
How to fix? The simplest hack would be to add a method to reset the counter, and call it in setUp(). To fix it properly, you need to think how to remove that singleton.
BЈовић's answer will get you there. It's likely that somewhere else in your test code another instance of Foo is created that increases the value of the static member.
This may be a less hacky solution and possibly useful if adding a public reset method is not applicable (i.e. you don't want to add test-specific code to your API):
Mock classes. Add a class that dervies from Foo. Change the access level of your static variable from private to protected and add the new reset method to the protected class. You can then refactor your test code to run off of the derived class.
Make FooTester a friend of Foo. Via class friend ship you're allowing your test code more manipulation over the class under test.
I recommend going with the mock route. Keeps the original class clean of any test specific hacks and allows you to be more aware of any exposures in its interface.

The effect of redundant testing functions inside a C++ class

When designing functions inside a C++ class, I often keep testing in mind. So when I finish all the functionalists of a class, very often several functions that are only used for testing purpose are added in the class as well. Take the following example:
class SimpleClass
{
public:
int a;
int b;
void fun1();
void fun2();
void testIntermediateResult();
private:
void _fun1();
void _fun2();
};
In this function testIntermediateResult is only needed for testing purpose. Is it a good practice just leave the function inside the class or should I do something like that:
class SimpleClass
{
public:
int a;
int b;
void fun1();
void fun2();
#ifdef TESTING
void testIntermediateResult();
#endif
private:
void _fun1();
void _fun2();
};
The philosophy here is when this class has been finished testing and will be given to the clients then TESTING will be defined and this function will not be inside the class. Therefore, my question is: is really needed to remove the testing function when the class is given to the client? Suppose the client will not use the testing function, what's the effect of adding several redundant testing functions inside a class? Thanks.
I'm assuming that your client is not going to be involved in testing the class that you're handing over. I would not want to add testing functions directly into the class itself as there's a possibility that they could disrupt the behaviour of the class. As for the client, I would prefer not to give them something with a test function in it since:
It's not necessary - it's not their job to test it.
They could decide to try to use it - who knows what'll happen then?
It's just simpler if they don't see it. As for using the pre-processor, this could be fraught with problems particularly if you have attributes that need to be guarded in the same way. If any of them are missed or your macro is redefined in the build process by the client then you could get run-time crashes due to class size mismatches etc.
I'd favour having a one-to-one external class to test your deliverable classes. Something like TestSimpleClass which performs the testing. There are a number of advantages to this approach:
It's entirely separate from your code and not built into it so you aren't bloating code or causing any potential issues with it.
It's going to test your class interface the way your client sees it (i.e. black box testing)
Because it's separate, you don't have to give it to your client - they never have to know about it.
If you really want to test the internals of the class, you can always make your test class a friend of your deliverable class. It's only one line extra in the deliverable class and you still don't have to ship your test classes or libraries.

Unit testing - setting private members to get desired object state

I'm taking my first steps with unit testing and have a problem with encapsulation. My class has some private member variables that shouldn't be visible to the client, but in order for me to put object in a state I want to test it under, I need to set those private variables.
Say I have a code like that:
Class Foo {
public:
int action() ;
private:
int state ;
} ;
int Foo::action()
{
if(this->state == 1)
return 1 ;
else
return 0 ;
}
So now I want to test Foo::action(), but I need to be able to set Foo::state to be able to check function under different scenarios. One solution is the evil "define private public" in tests code. But is there something more elegant? I would like to stress that Foo::state is a variable that shouldn't be accessed by client, so I don't want to declare any public setter.
Edit:
I now think that extending the class I want to test in test code and including setters in that derived class would work, providing I changed private variables to protected. But that's a 'one generation only' solution and still feels like a hack rather than a proper approach.
Edit 2:
After reading answers and comments I was given (thanks to Lieven and ap. in particular) I believe the actual class I'm trying to test now (not the simple example I provided) simply does too much and the answer to my problem is moving some of its logic into another class that will be used by the big guy.
There are only two posibilities (refactoring asside)
Use the public interface to set the state.
The state is redundant if you can't set it to through the public interface.
Option 2 is self explanatory and most likely not applicable to your case so you are left with setting the state through the public interface of your class.
As you have already mentioned, this is possible but it requires a lot of code to get to the right state. That in itself could be an indication that your class is currently doing to much and it's time to refactor parts of your class into smaller, testable classes.
From Do not test private methods
If you find the need to test a private method, then you’re doing
something else wrong. There is an “upstream” problem, so to speak. You
have arrived at this problem due to some other mistake previous in
this process. Try to isolate what that is, exactly, and remove that
rather than bending your tests to go down a painful road of
brittleness in testing.
and Unit testing private members
I'd recommend not unit testing private methods. Since they're
private, they may be changed in any conceivable (or inconceivable?)
manner between each release. If a given private method is so critical
to the operation of the class that you feel it deserves test cases,
then it's probably time to refactor that out into a protected or
public method
A common quote on this is
You should never touch your privates
If your test class is called MyTestClass, then add MyTestClass as friend in class Foo to be able to access its private member variables.
Class Foo {
public:
int action();
private:
int state;
friend class MyTestClass;
};
You should be having some publicly (or "protectedly") accessible mechanism to change the value of the private variable state. For simplicity, let's say it is a method Foo::setState(int inState). Use that in the unit test to change the state, and thus test the Foo::action() method. This ensures that any future implementation changes would not affect the unit test (unless the "API" Foo::setState() changes - in which case, of course, you have to change the unit test).
If you do not have such a mechanism to change state, it means the end user or calling code cannot change it either, and hence, you wouldn't need to test it (and maybe that makes state redundant, but I don't know about that).
If the private variable changes "indirectly" through other code, you will have to execute the same code in the unit test. You can always trace back any method visible externally to inputs fed to the code externally. Basically the point is that in the unit test, you would have to feed the same inputs to the code as in the "real" scenario, and then test if it responds as it should.
As discussed in the comments below, if the "path" from the input to the code being tested is too long, the code/test may have to be broken into smaller modules or intermediate points. To elaborate, consider the code flow as:
Input -> A -> B -> C -> Output
// A, B, C are intermediate execution points which are not "publicly accessible".
In the above case, all you can do is
Given Input, check if Output is correct.
Instead, it would be good to expose the intermediate A, B, C, at least to the unit tests, so that you can now break your test into:
Given Input, check if A is correct.
Given A, check if B is correct.
Given B, check if C is correct.
Given C, check if Output is correct.
As you can imagine, if the test fails, it becomes easier to figure out what failed, and hence to fix it.

Unit-testing a simple collection class

Consider the following class:
public class MyIntSet
{
private List<int> _list = new List<int>();
public void Add(int num)
{
if (!_list.Contains(num))
_list.Add(num);
}
public bool Contains(int num)
{
return _list.Contains(num);
}
}
Following the "only test one thing" principle, suppose I want to test the "Add" function.
Consider the following possibility for such a test:
[TestClass]
public class MyIntSetTests
{
[TestMethod]
public void Add_AddOneNumber_SetContainsAddedNumber()
{
MyIntSet set = new MyIntSet();
int num = 0;
set.Add(num);
Assert.IsTrue(set.Contains(num));
}
}
My problem with this solution is that it actually tests 2 methods: Add() and Contains().
Theoretically, there could be a bug in both, that only manifests in scenarios where they are not called one after the other. Of course, Contains() now servers as a thin wrapper for List's Contains() which shouldn't be tested in itself, but what if it changes to something more complex in the future? Perhaps a simple "thin wrap" method should always be kept for testing purposes ?
An alternative approach might suggest mocking out or exposing (possibly using InternalsVisibleTo or PrivateObject) the private _list member and have the test inspect it directly, but that could potentially create test maintainability problems if someday the internal list is replaced by some other collection (maybe C5).
Is there a better way to do this?
Are any of my arguments against the above implementations flawed?
Thanks in advance,
JC
Your test seems perfectly OK to me. You may have misunderstood a principle of unit testing.
A single test should (ideally) only test one thing, that is true, but that does not mean that it should test only one method; rather it should only test one behaviour (an invariant, adherence to a certain business rule, etc.) .
Your test tests the behaviour "if you add to a new set, it is no longer empty", which is a single behaviour :-).
To address your other points:
Theoretically, there could be a bug in both, that only manifests in scenarios where they are not called one after the other.
True, but that just means you need more tests :-). For example, add two numbers, then call Contains, or call Contains without Add.
An alternative approach might suggest mocking out or exposing (possibly using InternalsVisibleTo) the private _list member and have the test inspect it directly, but that could potentially create test maintainability problems[...]
Very true, so don't do this. A unit test should always be against the public interface of the unit under test. That's why it's called a unit test, and not a "messing around inside a unit"-test ;-).
There are two possibilities.
You've exposed a flaw in your design. You should carefully consider if the actions that your Add method is executing is clear to the consumer. If you don't want people adding duplicates to the list, why even have a Contains() method? The user is going to be confused when it's not added to the list and no error is thrown. Even worse, they might duplicate the functionality by writing the exact same code before they call .Add() on their list collection. Perhaps it should be removed, and replaced with an indexer? It's not clear from your list class that it's not meant to hold duplicates.
The design is fine, and your public methods should rely on each other. This is normal, and there is no reason you can't test both methods. The more test cases you have, theoretically the better.
As an example, say you have a functions that just calls down into other layers, which may already be unit tested. That doesn't mean you don't write unit tests for the function even if it's simply a wrapper.
In practice, your current test is fine. For something this simple it's very unlikely that bugs in add() and contains() would mutually conspire to hide each other. In cases where you are really concerned about testing add() and add() alone, one solution is to make your _list variable available to your unit test code.
[TestClass]
public void Add_AddOneNumber_SetContainsAddedNumber() {
MyIntSet set = new MyIntSet();
set.add(0);
Assert.IsTrue(set._list.Contains(0));
}
Doing this has two drawbacks. One: it requires access to the private _list variable, which is a little complex in C# (I recommend the reflection technique). Two: it makes your test code dependent on the actual implementation of your Set implementation, which means you'll have to modify the test if you ever change the implementation. I'd never do this for something as simple as a collections class, but in some cases it may be useful.