C++ 私有方法的单元测试
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3676664/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Unit testing of private methods
提问by Mumbles
I am in the process of writing some unit tests. In particular I want to test some private methods.
我正在编写一些单元测试。我特别想测试一些私有方法。
So far the I have come up with using.
到目前为止,我已经想出了使用。
#define private public
But I am not happy with this as it will destroy all encapsulation from the point of view of the unit test.
但我对此并不满意,因为从单元测试的角度来看,它会破坏所有封装。
What methods do you use to unit-test private methods.
您使用哪些方法对私有方法进行单元测试。
采纳答案by Mike Seymour
If the methods are complex enough to warrant testing in isolation, then refactor them into their own class(es) and test via their public interface(s). Then use them privately in the original class.
如果这些方法足够复杂以保证独立测试,那么将它们重构为它们自己的类并通过它们的公共接口进行测试。然后在原始类中私下使用它们。
回答by Anthony Williams
Rather than the nasty #define
hack you mention in the question, a cleaner mechanism is to make the test a friend of the class under test. This allows the test code (and just the test code) access to the privates, whilst protecting them from everything else.
与#define
您在问题中提到的讨厌的hack 不同,更简洁的机制是让测试成为被测类的朋友。这允许测试代码(以及仅测试代码)访问私有数据,同时保护它们免受其他任何事情的影响。
However, it is preferable to test through the public interface. If your class X has a lot of code in the private member functions then it might be worth extracting a new class Y which is used by the implementation of class X. This new class Y can then be tested through its public interface, without exposing its use to the clients of class X.
但是,最好通过公共接口进行测试。如果您的类 X 在私有成员函数中有很多代码,那么可能值得提取一个新类 Y,该类由类 X 的实现使用。然后可以通过其公共接口测试这个新类 Y,而不会暴露其用于 X 类的客户。
回答by jlstrecker
If you're using Google Test, you can use FRIEND_TESTto easily declare your test fixture as a friend to the class under test.
如果您使用的是 Google Test,则可以使用FRIEND_TEST轻松地将您的测试装置声明为被测类的好友。
And you know, if testing private functions were unequivocally bad like some of the other answers were saying, then it probably wouldn't be built into Google Test.
而且你知道,如果测试私有函数就像其他一些答案所说的那样毫无疑问是糟糕的,那么它可能不会被内置到谷歌测试中。
You can read more about when testing private functions is good or bad in this answer.
您可以在此答案中阅读更多有关何时测试私有函数是好是坏的信息。
回答by Manoj R
Make the test class as the friend of the original class. This friend declaration will be inside the #define UNIT_TEST
flag.
使测试类成为原始类的朋友。这个朋友声明将在#define UNIT_TEST
标志内。
class To_test_class {
#ifdef UNIT_TEST
friend test_class;
#endif
}
Now for your unit test you will compile the code with flag -DUNIT_TEST
. This way you will be able to test the private function.
现在对于您的单元测试,您将使用 flag 编译代码-DUNIT_TEST
。通过这种方式,您将能够测试私有函数。
Now your unit test code will not be pushed into production environment, as UNIT_TEST
flag will be false. Hence the code is still secure.
现在您的单元测试代码不会被推送到生产环境中,因为UNIT_TEST
flag 将为 false。因此代码仍然是安全的。
Also you will not need any special library for unit testing.
你也不需要任何特殊的库来进行单元测试。
回答by Milo?
I know this is an older question, but it seems that nobody has shared the relatively good method that I prefer, so here it goes:
我知道这是一个较老的问题,但似乎没有人分享我更喜欢的相对较好的方法,所以这里是:
Change the method you wish to test from private
to protected
. For other classes, the method is still going to be private
, but now you can derive a "testing" class from your base class that exposes the private functionality you want tested.
将您要测试的方法从 更改private
为protected
。对于其他类,该方法仍将是private
,但现在您可以从基类派生一个“测试”类,该类公开您要测试的私有功能。
Here's a minimal example:
这是一个最小的例子:
class BASE_CLASS {
protected:
int your_method(int a, int b);
};
class TEST_CLASS : public BASE_CLASS {
public:
int your_method(int a, int b) {
return BASE_CLASS::your_method(a, b);
}
}
Of course you will have to update your unit tests to run your tests on the derived class instead of the base class, but after that, any change made to the base class will be automatically reflected in the "testing" class.
当然,您必须更新单元测试才能在派生类而不是基类上运行测试,但在那之后,对基类所做的任何更改都将自动反映在“测试”类中。
回答by Pari
After many hours this is what I decided to be the best solution for ones that want to test their private functions. This is combination of answers by Max DeLisoand Milo?.
几个小时后,这就是我决定成为想要测试其私有功能的人的最佳解决方案的原因。这是Max DeLiso和Milo的答案组合?.
If you are using boost::unit-testthen there's an easy and elegant solution.
如果您使用的是boost::unit-test,那么有一个简单而优雅的解决方案。
Use
protected
instead ofprivate
in your classes/* MyClass.hpp */ class MyClass { protected: int test() { return 1; } };
Create a fixture:
/* TestMyClass.cpp */ class F : public MyClass {}; BOOST_FIXTURE_TEST_SUITE(SomeTests, F) // use any protected methods inside your tests BOOST_AUTO_TEST_CASE(init_test) { BOOST_CHECK_EQUAL( test(), 1 ); } BOOST_AUTO_TEST_SUITE_END()
在你的课程中 使用
protected
而不是private
/* MyClass.hpp */ class MyClass { protected: int test() { return 1; } };
创建夹具:
/* TestMyClass.cpp */ class F : public MyClass {}; BOOST_FIXTURE_TEST_SUITE(SomeTests, F) // use any protected methods inside your tests BOOST_AUTO_TEST_CASE(init_test) { BOOST_CHECK_EQUAL( test(), 1 ); } BOOST_AUTO_TEST_SUITE_END()
This way you can freely use any of the MyClass
functions without #define private public
or adding friendsto you class!
这样您就可以自由使用任何MyClass
功能,无需#define private public
或向您的班级添加朋友!
回答by Max DeLiso
The define hack is a horrible idea. Arbitrarily re-writing your code with the preprocessor when you go to compile it is never wise.
定义黑客是一个可怕的想法。在编译时随意使用预处理器重新编写代码是不明智的。
Now as several people have mentioned already, it's debatable whether you should be testing private methods at all. But this doesn't cover the case where you've intentionally hidden constructors to restrict instantiaton to certain scopes, or a few other more esoteric cases.
现在正如一些人已经提到的,您是否应该测试私有方法是有争议的。但这并不包括您有意隐藏构造函数以将实例化限制在某些范围内的情况,或者其他一些更深奥的情况。
Also, you can't friend a namespace and "friendship" is not inherited in C++ so depending on your unit testing framework you could be in trouble. Luckily, if you're using Boost.Test, there's in elegant solution to this issue in the form of Fixtures.
此外,您不能将命名空间与命名空间为好友,并且 C++ 中不会继承“友谊”,因此根据您的单元测试框架,您可能会遇到麻烦。幸运的是,如果您正在使用 Boost.Test,则可以通过 Fixtures 的形式优雅地解决此问题。
http://www.boost.org/doc/libs/1_52_0/libs/test/doc/html/utf/user-guide/fixture/per-test-case.html
http://www.boost.org/doc/libs/1_52_0/libs/test/doc/html/utf/user-guide/fixture/per-test-case.html
You can friend the fixture and have it instantiate all of the instances that you use in your unit testing functions, declaring them as static to the fixture and with module scope. If you're using a namespace don't worry, you can just declare your fixture within the namespace and your test cases outside of the namespace, and then use the scope resolution operator to get to the static members.
您可以将夹具添加为友元,并让它实例化您在单元测试函数中使用的所有实例,将它们声明为夹具的静态和模块范围。如果您正在使用命名空间,请不要担心,您只需在命名空间内声明您的夹具,在命名空间外声明您的测试用例,然后使用范围解析运算符来获取静态成员。
The BOOST_FIXTURE_TEST_CASE
macro will take care of instantiating and tearing down your fixture for you.
该BOOST_FIXTURE_TEST_CASE
宏将采取实例化和拆除的夹具你的照顾。
回答by aeh
I don't think unit test cases would be required for private methods.
我认为私有方法不需要单元测试用例。
If a method is private it can used only within that class. If you have tested all the public methods using this private method then there is no need to test this separately since it was used only in those many ways.
如果一个方法是私有的,它只能在该类中使用。如果您已经使用此私有方法测试了所有公共方法,则无需单独测试它,因为它仅以多种方式使用。