Unit test private method in c++ using a friend class

I know that this is a debated practice, but let’s suppose that this is the best option for me. I am wondering about what is the actual technique to do this. The approach that I see is this:

1) Make a friend class that of the class who’s method I want to test.

2) In the friend class, create a public method(s) that call the private method(s) of the tested class.

3) Test the public methods of the friend class.

Here is a simple example to illustrate the above steps:

#include <iostream>

class MyClass
{
  friend class MyFriend; // Step 1

  private:
  int plus_two(int a)
  {
    return a + 2;
  }
};

class MyFriend
{
public:
  MyFriend(MyClass *mc_ptr_1)
  {
    MyClass *mc_ptr = mc_ptr_1;
  }

  int plus_two(int a) // Step 2
  {
    return mc_ptr->plus_two(a);
  }
private:
  MyClass *mc_ptr;
};

int main()
{
  MyClass mc;
  MyFriend mf(&mc);
  if (mf.plus_two(3) == 5) // Step 3
    {
      std::cout << "Passed" << std::endl;
    }
  else
    {
      std::cout << "Failed " << std::endl;
    }

  return 0;
}

Edit:

I see that in the discussion following one of the answers people are wondering about my code base.

My class has methods that are called by other methods; none of these methods should be called outside the class, so they should be private. Of course they could be put into one method, but logically they are much better separate. These methods are complicated enough to warrant unit testing, and due to performance issues I will very likely have to re-factor these methods, hence it would be nice to have a test to make sure that my re-factoring didn’t break anything. I am not the only one working on the team, though I am the only one who is working on this project including the tests.

Having said the above, my question was not about whether it is a good practice to write unit tests for private methods, though I appreciate the feedback.

3

An alternative to friend (well, in a sense) that I use frequently is a pattern that I’ve come to know as access_by. It’s pretty simple:

class A {
  void priv_method(){};
 public:
  template <class T> struct access_by;
  template <class T> friend struct access_by;
}

Now, suppose class B is involved in testing A. You can write this:

template <> struct access_by<B> {
  call_priv_method(A & a) {a.priv_method();}
}

You can then use this specialization of access_by to call private methods of A. Basically, what this does is put the onus of declaring friendship into the header file of the class that wants to call A’s private methods. It also lets you add friends to A without changing A’s source. Idiomatically, it also indicates to whoever reads the source of A that A does not indicate B a true friend in the sense of extending its interface. Rather, the interface of A is complete as given and B needs special access into A (testing being a good example, I’ve also used this pattern when implementing boost python bindings, sometimes a function that needs to be private in C++ is handy to expose into the python layer for the implementation).

1

If it’s hard to test, it’s badly written

If you have a class with private methods complex enough to warrant their own test, the class is doing too much. Inside there is another class trying to get out.

Extract the private methods that you want to test into a new class (or classes) and make them public. Test the new classes.

In addition to making the code easier to test, this refactoring will make the code easier to understand and maintain.

4

You shouldn’t be testing private methods. Period. The classes using your class only care about the methods that it provides, not the ones it uses under the hood to work.

If you’re worrying about your code coverage, you need to find configurations that allow you to test that private method from one of the public method calls. If you can’t do that, what’s the point of having the method in the first place? It’s simply unreachable code.

26

There are a few options to do this, but keep in mind that they (in essence) modify the public interface of your modules, to give you access to internal implementation details (effectively transforming unit testing into tightly coupled client dependencies, where you should have no dependencies at all).

  • you could add a friend (class or function) declaration to the tested class.

  • you could add #define private public to the beginning of your test files, before #include-ing the tested code. In case the tested code is an already-compiled library though, this could make the headers no longer match already compiled binary code (and cause UB).

  • you could insert a macro in your tested class and decide at a later date what that macro means (with a different definition for testing code). This would allow you to test internals, but it would also allow third party client code to hack into your class (by creating their own definition in the declaration you add).

Here’s a questionable suggestion for a questionable question. I don’t like the coupling of friend as then released code has to know about the test. Nir’s answer is one way to alleviate that, but I still don’t much like changing the class to conform to the test.

Since I don’t rely on inheritance often, I sometimes just make the otherwise private methods protected and have a test class inherit and expose as needed. The reality is that the public API and the testing API can differ and still be distinct from the private API, which leaves you in sort of a bind.

Here’s a practical example that’s of the sort I resort to this trick for. I write embedded code, and we rely on state machines quite a bit. The external API doesn’t necessarily need to know about the internal state machine state, but the test should (arguably) test conformance to the state machine diagram in the design doc. I might expose a “current state” getter as protected and then give the test access to that, allowing me to test the state machine more fully. I often find this type of class hard to test as a black box.

1

You can write your code with lots of workarounds to stop you having to use friends.

You can write classes and never have any private methods at all. All you need to then do is make implementation functions within the compilation unit, let your class call them and pass in any data members they need to access.

And yes it will mean you can change the signatures or add new “implementation” methods without changing your header in the future.

You have to weigh up though whether or not it is worth it. And a lot will really depend on who is going to see your header.

If I’m using a 3rd party library I’d rather not see friend declarations to their unit testers. I don’t want to build their library either and have their tests run when I do. Unfortunately too many 3rd party open source libraries I have built do that.

Testing is the job of the writers of the library, not its users.

However not all classes are visible to the user of your library. Lots of classes are “implementation” and you implement them the best way to ensure they work properly. In those, you may still have private methods and members but want unit testers to test them. So go ahead and do it that way if that will lead to robust code quicker, that is easy to maintain for those who need to do so.

If the users of your class are all within your own company or team, you can also relax a bit more about that strategy, assuming it’s allowed by your company’s coding standards.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật