All right, do not get angry now, I know there are several questions about this topic, but I still have some doubts.
I think I totally agree about not testing private functions, I find it reasonable, but how can I test public methods that set private variables?
Let's say that the constructor set some private variables and I want to test that those variable are correctly set after the constructor is called. Is it a valid test? How should I check the value of the private variables without adding public getters?
I add a not real scenario example to try to be clearer:
public class ClassToTest
{
private bool _isOn;
public void SwitchOn() { _isOn = true; }
public void SwitchOff(){ _isOn = false; }
public void update()
{
if (_isOn)
DoSomething();
}
private void DoSomething()
{
//this could also execute a function of an external dependency. But still the dependency could not have a public function to test if the behavior actually ran.
}
}
how can I test that SwitchOn and SwitchOff work properly if I cannot test against the _isOn value? (this is an example, it implies that I will not write a public getter and the functions do not return a value because they do not need to)
Tests should use the Assemble/Activate/Assert pattern:
test switch on {
x = new ClassToTest();
x.SwitchOn(); // <-- Assemble an on switch
EmptyMailQueue(); // <-- Assemble nothing in the Q
PossiblySendUserEmail(); // <-- Activate the feature
assert(mailQueue.count() == 1);
}
test switch on {
x = new ClassToTest();
x.SwitchOff();
EmptyMailQueue();
PossiblySendUserEmail();
assert(mailQueue.count() == 0); // <-- Assert switch is off so no mails sent
}
You assert the actual reason you have a switch. Testing the switch itself breaks the rule "Don't TDD getters and setters".
You need to test private members, because they might have bugs in them.
"Private" is not a magic barrier, it's simply a convention advising production-code clients not to call that member directly.
Prepending all such member with an _underbar would be just as useful as C++ protecting such methods with hardware.
Your car engine has plugs inside that should not be used while driving, only when a mechanic tests things. Software should be the same. Test your private members, and disable private if you need to.
However...
The point of an object is to expose behavior. If your private variable is set correctly, then your object should behave correctly. Your tests should request this behavior.
Look up "Test-Driven Development" (and start using it yesterday), and look up "Intentional Programming". Your test cases should start by requesting that behavior, and should not worry about implementation details. If you upgrade an object to use different internals, you don't need too many tests breaking for no reason.
(Go not to elves, or software methodologists, for advice, for they will say both Yes and No!;)
Related
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 :)
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.
It seems as though the general consensus of the testing community is to not test private methods. Instead, you should test private methods by testing the public methods that invoke them. However, something just doesn't feel right to me. Let's take this method for example:
/**
* Returns the base name of the output generator class. If the class is named
* Reno_OutputGenerator_HTML, this would return "HTML".
*
* #return string
*/
protected function getName()
{
$class = get_class($this);
$matches = array();
if (preg_match('/^Reno_OutputGenerator_(.+)$', $class, $matches))
{
return $matches[1];
}
else
{
throw new Reno_OutputGenerator_Exception('Class name must follow the format of Reno_OutputGenerator_<name>.');
}
}
This particular function is used in a couple of places in my class. I'd like to test both branches of the if statement in this function, which would mean for each public function I'd have to test those 2 situations plus whatever else the public method itself does.
This is what feels weird for me. If I'm testing to see if getName() throws an Exception when a certain specific condition is met, then that means that I have to know implementation details of the private method. If I have to know that, then why shouldn't I just extend the class, make the method public, and test it that way?
(BTW: If you're wondering why such a weird method exists, this is used to automagically figure out what directory this class's template files are stored in).
The way I understand unit testing, this is exactly the kind of testing I would want to do. I have always looked at unit testing as white-box testing; if there's a branch point in my code, that means I need two unit tests to address it. I think the worst case I ever wound up with was a single method with 32 permutations.
The challenge with unit-testing is that if you don't explore all the edge cases by examining your code and figuring out all the different paths, you wind up missing one or more cases and possibly introducing subtle bugs into your application.
So, no, I don't see what you're proposing as weird. The method can stay internal, and you can add an extra test case - you probably only need the one with the exception, right?
Alternatively, you could refactor the functionality into a separate object that takes your generator object and returns its name (based on the algorithm above). That would justify separating the tests, because you'd have a name-extractor object, and the output generator implementations. I'm still not sure that this would save you a lot, because you'd still have to test the output generators to make sure they were using the name extractor correctly, but it would separate your functional and testing concerns.
You could also test this function by deriving from the class in your testclass like this:
namespace TheProject
{
public class ClassUnderTest
{
protected string GetName()
{
return "The name";
}
}
}
namespace TestProject
{
[TestClass]
public class TheTest:TheProject.ClassUnderTest
{
[TestMethod]
public void TestGetName()
{
string expected = "The name";
string actual = GetName();
Assert.AreEqual(expected, actual);
}
}
}
That way you keep your method private and you don't need to refactor your code to another class.
Assume i have a private routine that performs some calculation:
private function TCar.Speed: float
{
Result = m_furlogs * 23;
}
But now i want to begin testing this calculation more thoroughly, so i refactor it out to a separate function:
public function TCar.Speed: float
{
Result = CalculateSpeed(m_furlogs);
}
private function TCar.CalculateSpeed(single furlogs): float
{
Result = furlogs * 23;
}
Now i can perform all kinds of tests on CalculateSpeed:
Check( CalculateSpeed(0) = 0);
Check( CalculateSpeed(1) = 23);
Check( CalculateSpeed(2) = 46);
Check( CalculateSpeed(88) = -1);
Except that i can't perform these tests, because CalculateSpeed is private to TCar. An abstract tennant of unit-testing is that you never test private code - only public interfaces. As a practical matter, *x*Unit is not normally structured to be able to access private methods of the separate class being tested.
The issue is that none of the rest of the class is setup to handle unit-tests. This is the very first routine that will have testing of any kind. And it is very difficult to configure the host class a set of initial conditions that will allow me to test calling CalculateSpeed with every set of inputs that i would like.
The only alternative i can see, is moving this private calculation out into it's own TCarCalculateSpeed class:
public class TCarCalculateSpeed
{
public function CalculateSpeed(float furlogs)
{
Result = furlogs * 23;
}
}
A whole class, dedicated to exposing one method, that's supposed to be private, just so i can test it?
Class explosion.
Plus it's private. If i wanted it to be public, i'd rather promote it to public visibility - at least that way i save a separate class being created.
i'd like to add some unit-testing; but it can only be done in small pieces, as code changes. i can't completely redesign functioning 12 year old software, possibly breaking everything, because i wanted to test one internal calculation.
My current, best, thinking is to add a Test method to my Car class, and just call that:
TCar Car = new TCar();
Car.RunTests;
public procedure TCar.RunTests
{
Check( CalculateSpeed(0) = 0);
Check( CalculateSpeed(1) = 23);
Check( CalculateSpeed(2) = 46);
Check( CalculateSpeed(88) = -1);
}
But now i have to figure out how to have TCar.RunTests get trigged by the external TestRunner, which is only designed to use TestCase classes.
Note: i've tried my damnest to mix syntax from a bunch of languages. In other words: language agnostic.
This can't really be quite language-agnostic, as the protection mechanisms and the tactics to bypass them vary quite widely with language.
But most languages do provide bypasses in some form, and as others have noted, there are sometimes protections midway between private and public that make testing easier.
In Java, for example, reflection can be used to private stuff if you really need to, and things can be made protected or package-private so that you don't need reflection.
Generally speaking, if something is complex enough to require testing it should not be buried as a private method or class in something else. It is doing something that warrants its own class.
Rather than worrying about the number of classes, worry about their size and complexity. Many small classes adhering to the Single Responsibility Principle are better than a small number of classes doing complex things internally.
If a method is complicated (and risky) enough to test on its own, it's worth creating a class for it or making it a public member of the existing class - whichever is more suitable, given the characteristics of the existing class.
Can you create multiple instances of the TCar class with different initial values of m_furlogs? Do you have a getter on speed anywhere? You could validate against that if so.
If it's only internally used, and you really want to test it, you could create a utilities class that holds the logic for the simple calculations. I know it's refactoring, but it's not the class explosion you might be envisioning.
In some languages, there is middle ground between private and public. You can expose a logically private method to a unit test without exposing it to the world.
In method documentation, you can document that the method is intended private, but accessible for the purpose of unit-testing.
In Java, for example, you could make the private method package protected, and place the unit test in the same package. In C#, if I recall correctly, you could make it internal. In C++, the unit-test could be a friend.
If your language supports compiler defines, you could use these to your advantage.
(Example code in Delphi)
In your unit test project, set a compiler conditional define, either using the project options or in an include file that you include in each and every unit in that project.
{$DEFINE UNIT_TESTS}
In your class code, check the conditional define and switch between public or protected and private accordingly:
{$IFDEF UNIT_TESTS}
public // or protected
{$ELSE}
private
{$ENDIF}
function CalculateSpeed: float;
This means your unit tests will have the access they need to your method, while in production code it will still be private.
Say I have an interface IFoo which I am mocking. There are 3 methods on this interface. I need to test that the system under test calls at least one of the three methods. I don't care how many times, or with what arguments it does call, but the case where it ignores all the methods and does not touch the IFoo mock is the failure case.
I've been looking through the Expect.Call documentation but can't see an easy way to do it.
Any ideas?
You can give rhino mocks a lambda to run when a function get's called. This lambda can then increment a counter. Assert the counter > 1 and you're done.
Commented by Don Kirkby:
I believe Mendelt is referring to the Do method.
Not sure this answers your question but I've found that if I need to do anything like that with Rhino (or any similiar framework/library), anything that I didn't know how to do upfront, then I'm better just creating a manual mock.
Creating a class that implements the interface and sets a public boolean field to true if any of the methods is called will be trivially easy, you can give the class a descriptive name which means that (most importantly) the next person viewing the code will immediately understand it.
If I understood you correctly you want to check that the interface is called at least once on any of three specified methods. Looking through the quick reference I don't think you can do that in Rhino Mocks.
Intuitively I think you're trying to write a test that is brittle, which is a bad thing. This implies incomplete specification of the class under test. I urge you to think the design through so that the class under test and the test can have a known behavior.
However, to be useful with an example, you could always do it like this (but don't).
[TestFixture]
public class MyTest {
// The mocked interface
public class MockedInterface implements MyInterface {
int counter = 0;
public method1() { counter++; }
public method2() { counter++; }
public method3() { counter++; }
}
// The actual test, I assume you have the ClassUnderTest
// inject the interface through the constructor and
// the methodToTest calls either of the three methods on
// the interface.
[TestMethod]
public void testCallingAnyOfTheThreeMethods() {
MockedInterface mockery = new MockedInterface();
ClassUnderTest classToTest = new ClassUnderTest(mockery);
classToTest.methodToTest();
Assert.That(mockery.counter, Is.GreaterThan(1));
}
}
(Somebody check my code, I've written this from my head now and haven't written a C# stuff for about a year now)
I'm interested to know why you're doing this though.