Forcing to use a specific constructor, used exclusively in a certain code, nowhere else

Sometimes we need to provide a specific constructor solely for using the test. How can we force such a constructor to be used only in test code, nowhere else. I just wonder if this is possible in C ++ 11/14. eg,

class A { public: A() = default; // used only in test code } class A_Test : public ::testing::Test { private: A a; // it is ok. }; class A_Production { private: A a; // compiler error } 

I could imagine how to use the friend decorator and put the specific constructor in protected to restrict access. but there are other existing friends in legacy code. Is it possible to create a custom qualifier such as protected in C ++ 1x?

any ideas?

+6
source share
3 answers

You can use the password idiom :

Instead of direct friendships, you restrict access to A from A_Test through the indirect provision of ConstructorKey , which A uses in its interface where it needs ConstructorKey friends.

 class A { class ConstructorKey { friend class A_Test; private: ConstructorKey() {}; ConstructorKey(ConstructorKey const&) = default; }; public: // Whoever can provide a key has access: explicit A(ConstructorKey); // Used only in test code }; class A_Test : public ::testing::Test { private: A a {ConstructorKey{}}; // OK }; class A_Production { private: A a {ConstructorKey{}}; // Compiler error }; 
+3
source

I can come up with several ways to do this.

  • Create the protected constructor using only a test subclass.

  • Add forward the declaration to some dummy class class TestClassThatShouldNotBeUsedInProductionCode; , then declare a constructor that references this class as a parameter:

     A::A( /* other constructor arguments */, const TestClassThatShouldNotBeUsedInProductionCode &) 

This constructor can simply completely ignore this parameter. Your test module can define this dummy, an empty class: class TestClassThatShouldNotBeUsedInProductionCode {}; and be able to create your class A using it. Then only your test module can use this constructor, and its name allows you to understand what the purpose of this is. In fact, there is no way to define specific translation units as "real" code compared to "test" code, in C ++, you just want to implement a clear policy that will be difficult to break by accident.

Some options are possible, for example, using an inner class instead of directly declaring an autonomous class. An inner class can only be created with test code.

+1
source

Alternatively, in a cpp file that does A testing:

 #define private public #include "ClassA.h" // ready for testing :) 
-one
source

Source: https://habr.com/ru/post/1012340/


All Articles