Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Boost unit test: adding a helper method or private function

I have a BOOST_AUTO_TEST_CASE which needs a helper function. I could just make this a regular function and call it from within; but I'd rather somehow keep it local and private to the scope of the BOOST_AUTO_CASE. I'd also like to be able to declare vars which are in the scope of both the test case and the helper functions (e.g. const int serverCount = 10;).

If the test case was a class (and not a macro), I'd simply use a private member function. How do I do this (or the equivalent) for a Boost unit test case?

like image 222
SRobertJames Avatar asked May 28 '15 02:05

SRobertJames


People also ask

Should I write unit test for private methods?

Unit Tests Should Only Test Public Methods The short answer is that you shouldn't test private methods directly, but only their effects on the public methods that call them. Unit tests are clients of the object under test, much like the other classes in the code that are dependent on the object.

Should I make a private method public for testing?

A unit test should test the public contract, the only way how a class could be used in other parts of the code. A private method is implementation details, you should not test it; as far as public API works correctly, the implementation doesn't matter and could be changed without changes in test cases.

Is it good practice to make all methods public?

Yes it is very bad practice - you're letting your tools make design decisions for you. I think the main problem here is that you're trying to treat each individual method as a unit. This is generally the cause of all unit test woes.


1 Answers

Luckily there is a solution for this right in the Boost test framework: Fixtures. There are different types of fixtures but in your case the per test case fixture seems to fit.

#define BOOST_TEST_MODULE example
#include <boost/test/included/unit_test.hpp>

struct TestContext {
    TestContext() : testVar( 0 ) { BOOST_TEST_MESSAGE( "setup fixture" ); }
    ~TestContext()               { BOOST_TEST_MESSAGE( "teardown fixture" ); }

    int testVar;

    void helperMethod(int x, double y)
    {
        testVar = x * (int)y;
    }
};

BOOST_FIXTURE_TEST_CASE( test_case1, TestContext )
{
    BOOST_CHECK( testVar == 1 );
    ++testVar;
}

BOOST_FIXTURE_TEST_CASE( test_case2, TestContext )
{
    helperMethod(2, 3.1);
    // ...
}

testVar is accessible in the test case as well as in the TestContext class / struct. TestContext's constructor and destructor are called right before and after each test case respectively. They are not needed but can come in handy if you have to manage memory for example. In particular each test case is run with its own fresh instance of TestContext.

Update: Still valid for Boost 1.66, link updated.

like image 99
TobiMcNamobi Avatar answered Sep 29 '22 23:09

TobiMcNamobi