I use Boost Test for unit tests. I typically have a fixture struct:
class ClassBeingTested
{
protected:
int _x; // Want to access this directly in my unit tests
};
struct TestFixture : public ClassBeingTested
{
// I can access ClassBeingTested::_x here but it means i have to add getters for each test to call
ClassBeingTested _bla;
};
However, even if my fixture inherits from ClassBeingTested or uses a friend relationship I cannot access private/protected methods/state from each individual test:
BOOST_FIXTURE_TEST_CASE(test1, TestFixture)
{
_bla.doSomething();
BOOST_REQUIRE_EQUAL(_bla.x, 10); // Compiler error. I cannot access ClassBeingTested::_x here
}
only the fixture, which means I have to add a new getter (or test) for each access I wish to make.
Is there any way to achieve this? I have to add public getter methods to ClassBeingTested which are only used by tests, which isn't ideal.
(Please no replies of 'test using the public interface', that's not always possible).
You can make a friend test buddy, struct ClassBeingTestedBuddy; with friend struct ClassBeingTestedBuddy; in the class ClassBeingTested.
Have the test buddy class expose all the protected or private variables or methods that you need for all your tests.
It'd look like...
struct ClassBeingTestedBuddy {
ClassBeingTested* obj;
ClassBeingTestedBuddy(ClassBeingTested* obj_)
: obj{obj_} {}
};
...plus anything else you'd want to expose.
This is but one way of allowing the tests a bridge to the protected and private data and methods. But since it is all code in your project, for your testing use, it is a reasonable way of getting the test code access without too much instrumenting your actual code.
Related
I am using QTestLib for Unit Testing and i ask myself how to test private member functions of my classes. I would like to build a test suite for an in-house shared library.
What strategies do i have in Qt's context for this ?
I thought that testing private member functions through public members functions could be a good starting point :
class A {
public:
// add an extra function that is only relevant for testing
int value() const {
return theFunctionIWantToTest();
}
private:
int theFunctionIWantToTest() {
// implementation ..
}
}
But the problem is that i don't need this getter in the class A after testing.
I am not very experienced with QTestLib and so far i could not find anything in Qt's Doc related to this specific point.
Thanks.
Four possible solutions in reverse order of personal preference:
Set #define private public before include the class header. Non-portable unfortunately. (or luckily as some will say).
Declare your QTestLib test class to be a friend of class A
Move the gist of the function into a dedicated function in a separate file that is clearly marked as private API and forwared the call from the member function. Think of the a_p.h headers used by Qt itself.
Settle on testing the public interface only. I.e. either give up on the goal to test private functions or accept that the function simply should be public in the first place.
In unit testing with help of mock/fake objects, I wonder whether it's more preferable to initialize the mocks in SetUp or in the test method itself, if my test class contains methods that test the same class (and thus, fake object needed should be the same for all test case). Something like this:
class FooTests
{
Mock<IBar> mockBar;
Foo fooUnderTest;
[SetUp]
public void Setup()
{
mockBar = new Mock<IBar>();
fooUnderTest = new fooUnderTest(mockBar.Object);
}
[Test]
public void MyTest()
{
//setup mock methods
mockBar.SetUp( ... )
//test
fooUnderTest.TestSomething()
//assert something here
}
}
It seems that this will prevent us from duplicating code to mockBar and fooUnderTest in each test case, but the downside is that I have to declare class variables mockBar and fooUnderTest (or is this really a downside?), and it will be problematic if I want to have some special setup (for example, if in some testcase I want to overriede some of the virtual methods of Foo). Any suggestion what is the best practice?
If there is some common setup shared by all tests in a suite/fixture (including setting up some expectations on mock collaborators), MOVE to a Setup method. (Ditto for incidental details that are not relevant to the reader within the test)
If one test case wants to extend common setup, add the specific setup inline within test-case itself
If one test case wants a different setup (inspite of significant overlap), MOVE to different test suite and figure out some other mechanism to share setup (e.g. via composition, utility methods, Object Mothers, etc.)
I'm writing unit tests for my app, and now I've stumbled on a class in which I should test private methods. This could be result of poor design of particular class, but I must do it. Is there any way in Qt to call private methods, maybe using QMetaObject or something similar ?
For unit testing I am using QTestLib framework.
The proper (read annoying) answer is that you should not be testing private methods, those are implementation details ;-).
OTOH -- have you thought about conditionally declaring them protected/private depending on whether you are in testing or no and then extending? I've used that to get me out of a similar pinch in the past.
#ifdef TESTING
// or maybe even public!
#define ACCESS protected
#else
#define ACCESS private
#endif
/* your class here */
class Foo {
ACCESS
int fooeyness;
}
// or better yet, place this in a different file!
#ifdef TESTING
/*
class which extends the tested class which has public accessors
*/
#endif
Solution 1, quick and easy: make the test class(es) a friend of the public one.
class Foo {
// ...
private:
friend class FooTest;
};
This way your FooTest class can access all members of the public class. However, this way you need to modify the original class every time you want to access private data from a different test, and you leak information about the tests in the public API, and you possibly open up for class naming conflicts (what if there's /another/ FooTest class around?), and so on.
Solution 2, aka properly done: don't put private methods in the public class, but make a private class with public methods.
class Foo {
//
private:
friend class FooPrivate;
FooPrivate *d;
};
FooPrivate gets declared in its own header, which may not be installed, or stay in a include-privates/ subdirectory, or whatever -- i.e. it stays out of the way for normal usage. The public class stays clean this way.
class FooPrivate {
public:
// only public stuff in here;
// and especially this:
static FooPrivate *get(Foo *f) { return f->d; }
};
The test then includes the private header and calls FooPrivate::get(fooObj) to get the private class instance and then happily uses it.
I disagree with the "private members are implementation details" mentality, in my mind that roughly translates to "test only part of your code".
I can related to "units are units" argument, but why not try to cover as much of your code with tests as possible, even inside units? Aka. giving your units a thorough rectal examination.
And with this image in mind, one approach that I have been using frequently that is not mentioned in the other answers is to do the following:
Always declare members you want to test as protected in stead of private in your code.
Subclass your class in the testcode and simply make the selectors you need or simply write the test-code directly as members in that sub-class's implementation.
NOTE: You have to be careful with classes that rely on complex instantiation patterns to ensure that you construct them correctly (read: call the original class' constructor from the subclass ctor).
I have found more convenient way to do this. First, all private methods should be private slots.
Then you create an instance of the class:
Foo a;
Then we can use QMetaObject::invokeMethod to call any slot that method has (public or private). So if we want to call method Test, we can do it like this:
QMetaObject::invokeMethod(&a, "Test", Qt::DirectConnection);
Also, we can have return value and send arguments ... Actually, everything is answered here: http://doc.qt.nokia.com/stable/qmetaobject.html#invokeMethod
I've once read that Unit Test should test the class public interface, and not the protected/private stuff.
Your class should just behave right from outside. If implementation strategy changes, your Unit Test class is still the same.
Our team has members who are just ramping up on unit testing and we're struggling with some terminology. I'd like to determine a name for a particular pattern. I'm hoping there's one that's already embraced by other developers, but if not, I'd like to come up with one that's descriptive and will make talking about test strategies easier.
This pattern is used quite a bit for testing abstract methods, but is also handy when an object creates a new object (for cases where DI doesn't work or isn't desired). The basic pattern is to use an inner class that extends the class under test to expose protected methods.
Consider the following code (which is pseudocode, based on Java, but should translate to most languages):
The class to test:
public class MyClass {
public void send() {
//do something
}
protected MailMessage createNewMailMessage() {
return new MailMessage();
}
}
The test:
public class MyClassTest {
private MyClass myClass = new TestableMyClass();
private MailMessage mockMessage = mock(MailMessage.class);
public void setup() {
((TestableMyClass)myClass).setMailMessage(mockMessage);
}
// Do some tests //
private class TestableMyClass extends MyClass {
private MailMessage mailMessage;
public void setMailMessage(MailMessage mailMessage) {
this.mailMessage = mailMessage;
}
protected MailMessage createNewMailMessage() {
return mailMessage;
}
}
}
So, what do you call this pattern? TestableMyClass a "Mock" object, but since it's not managed by a mocking framework, it seems like there should be another term to describe this pattern. Any suggestions or ideas?
I'd call it a stub. As you said, it's not a true "mock", since its behavior isn't being controlled by a mocking framework, but is a "true" object.
You don't need to use a mocking framework to call something a Mock/Stub object - your MyClassTest (which I'm assuming is supposed to extend MyClass) is just a Stub.
I don't think there's a particular name for the case where Mocks/Stubs are defined as inner classes of your test class - and in the particular example here, there's no reason for it to be an inner class - it could just be a package protected class (in the same file as MyClassTest or in its separate file..)
Mock contains test assertions.
Stub provides simple hard-coded values to make the test work.
Fake provides complex behavior/answers.
I usually add two underscores prefixing the inner class for testing so it doesn't show up in auto-complete, e.g. '__TestableMyClass'. Also if you are using Mockito you should be stubbing like so
MyClass myClass = mock(MyClass.class);
when(myClass.createNewMailMessage()).thenReturn(mockMessage);
Unit Testing:
I have the following classes
public class BImpl extends AImpl
{
public BImpl(final C c)
{
super(c);
}
public String getInfo()
{
final String info = getInformation();
// Do all my logic here
return info;
}
}
public abstract class AImpl
{
public String getInformation()
{
// some logic...returns String.
}
}
I am trying to unit test the method getInfo() by using any of the mocking methods available either Mockito or JMock.
for example when using Mockito I am using this way:
final AImpl aImpl = mock(AImpl.class);
when(aImpl.getInformation()).thenReturn("ABC");
Now since I have to create an instance of BImpl the only way I can create is using the constructor available.
final BImpl bImpl = new BImpl (C);
bImpl.getInfo();
when it calls into the getInfo() method and it tries to call getInformation(), it isn't calling the mocked object but calling the actual one.
What is the good way to test this method.
Is there any other way I can create an instance of BImpl without going by the constructor that I have given above?
Thanks!!
IMHO it's not a problem with mocking libraries but with your design. You want to test getInfo() method by mocking getInformation() on which it depends. Unit testing a method mocking all its dependencies is a right way to go and all mocking frameworks support it pretty well. So why you experience these problems?
Because you have chosen inheritance where composition was actually needed. You are abusing inheritance to implement uses relationship, whereas it should have been composition. Inheriting from a class just to have a convenient access to its methods is asking for trouble. Think of extending EntityManager by every repository/DAO...
You should refactor your code first so that BImpl has AImpl and the latter one is injected somehow. Then you can let some DI framework to perform the injection in production code (or do it yourself) with real implementation while injecting mock in unit test.