Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8266641
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 8, 20262026-06-08T05:14:07+00:00 2026-06-08T05:14:07+00:00

Today I had a discussion with a colleague on whether to test or not

  • 0

Today I had a discussion with a colleague on whether to test or not to test private members or private state in the class. He almost convinced me why it makes sense. This question does not aim to duplicate already existing StackOverflow questions about the nature and reason of testing private members, like: What is wrong with making a unit test a friend of the class it is testing?

Colleagues suggestion was in my opinion a bit fragile to introduce the friend declaration to the unit test implementation class. In my opinion this is a no-go, because we introduce some dependency of tested code to the test code, whereas test code already depends on tested code => cyclic dependency. Even such innocent things like renaming a test class results in breaking unit tests and enforces code changes in tested code.

I’d like to ask C++ gurus to judge on the other proposal, which relies on the fact that we are allowed to specialize a template function. Just imagine the class:

// tested_class.h

struct tested_class 
{
  tested_class(int i) : i_(i) {}

  //some function which do complex things with i
  // and sometimes return a result

private:
  int i_;
};

I don’t like the idea to have a getter for i_ just to make it testable. So my proposal is ‘test_backdoor’ function template declaration in the class:

// tested_class.h

struct tested_class 
{
  explicit
  tested_class(int i=0) : i_(i) {}

  template<class Ctx>
  static void test_backdoor(Ctx& ctx);

  //some function which do complex things with i
  // and sometimes return a result

private:
  int i_;
};

By adding just this function we can make the class’ private members testable. Note, there is no dependency to unit test classes, nor the template function implementation. In this example the unit test implementation uses Boost Test framework.

// tested_class_test.cpp

namespace
{
  struct ctor_test_context
  {
    tested_class& tc_;
    int expected_i;
  };
}

// specialize the template member to do the rest of the test
template<>
void tested_class::test_backdoor<ctor_test_context>(ctor_test_context& ctx)
{
  BOOST_REQUIRE_EQUAL(ctx.expected_i, tc_.i_);
}

BOOST_AUTO_TEST_CASE(tested_class_default_ctor)
{
  tested_class tc;
  ctor_test_context ctx = { tc, 0 };
  tested_class::test_backdoor(ctx);
}

BOOST_AUTO_TEST_CASE(tested_class_value_init_ctor)
{
  tested_class tc(-5);
  ctor_test_context ctx = { tc, -5 };
  tested_class::test_backdoor(ctx);
}

By introducing just a single template declaration, which is not callable at all, we give the test implementer a possibility to forward test logic into a function. The function, acts on type safe contexts and is only visible from inside the particular test compilation unit, due to anonymous type nature of test context. And the best thing is, we can define as many anonymous test contexts as we like and specialize tests on them, without ever touching the tested class.

Sure, the users must know what template specialization is, but is this code really bad or weird or unreadable? Or can I expect from C++ developers to have the knowledge what C++ template specialization is and how it works?

Elaborating on using friend to declare unit test class I don’t think this is robust. Imagine boost framework (or may be other test frameworks). It generates for every test case a separate type. But why should I care as long I can write:

BOOST_AUTO_TEST_CASE(tested_class_value_init_ctor)
{
  ...
}

If using friends, I had to declare each test case as a friend then… Or end up introducing some test functionality in some common type (like fixture), declare it as a friend, and forward all test calls to that type… Isn’t that weird?

I would like to see your pro and cons practicing this approach.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-08T05:14:09+00:00Added an answer on June 8, 2026 at 5:14 am

    What will follow is not technically speaking a straight answer to your
    question as it will still make use of the “friend” functionality
    but it does not require modification of the tested entity itself
    and I think it addesses the concern of breaking the encapsulation
    mentioned in some of the other answers; it does though require
    writing some boilerplate code.

    The idea behind it is not mine and the implementation is
    entirely based on a trick presented and explained by litb on his
    blog
    (coupled with this Sutter’s gotw for just a little bit
    more context, at least for me) – in short CRTP, friends, ADL and pointers to members
    (I must confess that to my dismay the ADL part I still don’t
    get it entirely, but I’m relentesly working in figuring it out 100%).

    I tested it with gcc 4.6, clang 3.1 and VS2010 compilers and it
    works perfectly.

    /* test_tag.h */
    #ifndef TEST_TAG_H_INCLUDED_
    #define TEST_TAG_H_INCLUDED_
    
    template <typename Tag, typename Tag::type M>
    struct Rob
    {
        friend typename Tag::type get(Tag)
        {
            return M;
        }
    };
    
    template <typename Tag, typename Member> 
    struct TagBase
    {
        typedef Member type;
        friend type get(Tag);
    };
    
    
    #endif /* TEST_TAG_H_INCLUDED_ */
    
    /* tested_class.h */
    #ifndef TESTED_CLASS_H_INCLUDED_
    #define TESTED_CLASS_H_INCLUDED_
    
    #include <string>
    
    struct tested_class
    {
        tested_class(int i, const char* descr) : i_(i), descr_(descr) { }
    
    private:
        int i_;
        std::string descr_;
    };
    
    /* with or without the macros or even in a different file */
    #   ifdef TESTING_ENABLED
    #   include "test_tag.h"
    
        struct tested_class_i : TagBase<tested_class_i, int tested_class::*> { };
        struct tested_class_descr : TagBase<tested_class_descr, const std::string tested_class::*> { };
    
        template struct Rob<tested_class_i, &tested_class::i_>;
        template struct Rob<tested_class_descr, &tested_class::descr_>;
    
    #   endif
    
    #endif /* TESTED_CLASS_H_INCLUDED_ */
    
    /* test_access.cpp */
    #include "tested_class.h"
    
    #include <cstdlib>
    #include <iostream>
    #include <sstream>
    
    #define STRINGIZE0(text) #text
    #define STRINGIZE(text) STRINGIZE0(text)
    
    int assert_handler(const char* expr, const char* theFile, int theLine)
    {
        std::stringstream message;
        message << "Assertion " << expr << " failed in " << theFile << " at line " << theLine;
        message << "." << std::endl;
        std::cerr << message.str();
    
        return 1;
    }
    
    #define ASSERT_HALT() exit(__LINE__)
    
    #define ASSERT_EQUALS(lhs, rhs) ((void)(!((lhs) == (rhs)) && assert_handler(STRINGIZE((lhs == rhs)), __FILE__, __LINE__) && (ASSERT_HALT(), 1)))
    
    int main()
    {
        tested_class foo(35, "Some foo!");
    
        // the bind pointer to member by object reference could
        // be further wrapped in some "nice" macros
        std::cout << " Class guts: " << foo.*get(tested_class_i()) << " - " << foo.*get(tested_class_descr()) << std::endl;
        ASSERT_EQUALS(35, foo.*get(tested_class_i()));
        ASSERT_EQUALS("Some foo!", foo.*get(tested_class_descr()));
    
        ASSERT_EQUALS(80, foo.*get(tested_class_i()));
    
        return 0; 
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I had a discussion with a colleague today around using query strings in REST
A discussion I had with a colleague today. He claims whenever you use a
Today I had a discussion with a colleague about nested functions in Javascript: function
I had this interesting discussion today with a colleague. We were debating two pieces
I had a discussion with a friend today and he claimed that by using
Today I had a discussion with a friend of mine and we debated for
Today we had a discussion at the office about UI elements in the required
I am pretty sure about my answer but today had a discussion with my
Today we had a very heated discussion at work regarding the availability of a
Kind of a special question today :) I just had a test at my

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.