C++中私有方法的单元测试

rks48beu  于 2023-05-20  发布在  其他
关注(0)|答案(8)|浏览(236)

我正在编写一些单元测试。特别是我想测试一些私有方法。
到目前为止,我已经使用了。

#define private public

但我对此并不满意,因为从单元测试的Angular 来看,它将破坏所有的封装。
你用什么方法对私有方法进行单元测试。

uubf1zoe

uubf1zoe1#

与您在问题中提到的讨厌的#define hack不同,更干净的机制是使测试成为被测类的朋友。这允许测试代码(并且仅测试代码)访问私有对象,同时保护它们免受其他任何事情的影响。
但是,最好通过公共接口进行测试。如果你的类X在私有成员函数中有很多代码,那么提取一个新的类Y可能是值得的,它被类X的实现所使用。这个新的类Y可以通过它的公共接口进行测试,而不需要向类X的客户端公开它的使用。

yi0zb3m4

yi0zb3m42#

如果您使用的是GoogleTest,那么您可以使用FRIENDTEST轻松地将您的测试夹具声明为被测类的友元。
你知道,如果测试私有函数像其他一些答案所说的那样毫无疑问是不好的,那么它可能不会被内置到Google测试中。
你可以在这个答案中阅读更多关于测试私有函数是好是坏的信息。

kgqe7b3p

kgqe7b3p3#

如果方法复杂到需要单独测试,那么将它们重构到自己的类中,并通过它们的公共接口进行测试。然后在原始类中私下使用它们。

jdgnovmf

jdgnovmf4#

让测试班成为原班的朋友。这个friend声明将在#define UNIT_TEST标志内。

class To_test_class {
   #ifdef UNIT_TEST
     friend test_class;
   #endif
}

现在,对于单元测试,您将编译带有标志-DUNIT_TEST的代码。这样你就可以测试私有函数。
现在你的单元测试代码将不会被推送到生产环境中,因为UNIT_TEST标志将为false。因此,代码仍然是安全的。
你也不需要任何特殊的库来进行单元测试。

k2fxgqgv

k2fxgqgv5#

我知道这是一个老问题,但似乎没有人分享我更喜欢的相对好的方法,所以这里是:
将要测试的方法从private更改为protected。对于其他类,方法仍然是private,但是现在可以从基类派生一个“测试”类,它公开了您想要测试的私有功能。
下面是一个简单的例子:

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);
    }
}

当然,你将不得不更新你的单元测试,以便在派生类而不是基类上运行你的测试,但是在那之后,对基类所做的任何更改都将自动反映在“测试”类中。

dy2hfwbg

dy2hfwbg6#

几个小时后,我决定这是那些想要测试其私有功能的人的最佳解决方案。这是Max DeLisoMiloš的答案组合。
如果你正在使用boost::unit-test,那么有一个简单而优雅的解决方案。
1.在类中使用protected而不是private

/* MyClass.hpp */

class MyClass {

protected:
    int test() {
        return 1;
    }
};

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()

这样你就可以自由地使用任何MyClass函数,而不需要#define private public或向你的类添加 * 朋友 *!

wgeznvg7

wgeznvg77#

定义黑客是一个可怕的想法。在编译代码时,任意地用预处理器重写代码是不明智的。
现在,正如一些人已经提到的,是否应该测试私有方法还存在争议。但这并不包括你故意隐藏构造函数以将示例化限制在某些范围内的情况,或者其他一些更深奥的情况。
另外,你不能将一个名称空间加为好友,而“友谊”在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
您可以将fixture友元化,并让它示例化您在单元测试函数中使用的所有示例,将它们声明为fixture的静态的,并具有模块范围。如果您使用的是一个名称空间,请不要担心,您可以在名称空间内声明您的fixture,在名称空间外声明您的测试用例,然后使用范围解析操作符来获取静态成员。
BOOST_FIXTURE_TEST_CASE宏将负责示例化和拆除fixture。

gwo2fgha

gwo2fgha8#

我不认为私有方法需要单元测试用例。
如果一个方法是私有的,那么它只能在这个类中使用。如果你已经使用这个私有方法测试了所有的公共方法,那么就没有必要单独测试这个私有方法,因为它只被用在很多方面。

相关问题