代码之家  ›  专栏  ›  技术社区  ›  Mumbles

私人方法的单元测试[副本]

  •  87
  • Mumbles  · 技术社区  · 16 年前

    我正在写一些单元测试。 特别是我想测试一些私有方法。

    到目前为止,我已经想出了使用。

    #define private public
    

    但我对此并不满意,因为从单元测试的角度来看,它会破坏所有的封装。

    您使用什么方法对私有方法进行单元测试。

    8 回复  |  直到 8 年前
        1
  •  57
  •   Mike Seymour    16 年前

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

        2
  •  71
  •   Anthony Williams    16 年前

    而不是讨厌的 #define 你在问题中提到,一个更清晰的机制是让测试成为被测类的朋友。这就允许测试代码(以及测试代码)访问私密人员,同时保护他们不受其他任何影响。

    但是,最好通过公共接口进行测试。如果您的类X在私有成员函数中有很多代码,那么它可能值得提取一个新的类Y,该类Y由类X的实现使用。然后可以通过它的公共接口测试这个新的类Y,而不必向类X的客户机公开它的使用。

        3
  •  59
  •   Community Mohan Dere    9 年前

    如果你使用谷歌测试,你可以使用 FRIEND_TEST 轻松地将测试夹具声明为被测试类的朋友。

    你知道,如果测试私有函数像其他一些答案所说的那样毫无疑问是糟糕的,那么它可能不会被内置到谷歌测试中。

    您可以阅读更多关于测试私有函数好坏的信息。 in this answer .

        4
  •  29
  •   Elias Kosunen    9 年前

    使测试类成为原始类的朋友。这个朋友声明将在 #define UNIT_TEST 旗帜。

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

    现在,对于单元测试,您将使用标志编译代码 -DUNIT_TEST . 这样您就可以测试私有函数了。

    现在,您的单元测试代码将不会被推送到生产环境中,因为 UNIT_TEST 标志将为假。因此,代码仍然是安全的。

    此外,您不需要任何特殊的库来进行单元测试。

        5
  •  11
  •   MiloÅ¡    11 年前

    我知道这是一个古老的问题,但似乎没有人分享过我喜欢的相对好的方法,所以这里是:

    更改要测试的方法 private 到 protected . 对于其他类,该方法仍然是 私有的 但是现在您可以从您的基类派生一个“测试”类,它公开了您想要测试的私有功能。

    下面是一个最小的例子:

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

    当然,您必须更新单元测试才能在派生类而不是基类上运行测试,但是在这之后,对基类所做的任何更改都将自动反映在“测试”类中。

        6
  •  5
  •   Max DeLiso    13 年前

    定义黑客是一个可怕的想法。当你去编译代码时,用预处理器随意地重新编写代码是不明智的。

    现在正如一些人已经提到的,您是否应该测试私有方法还存在争议。但这并不包括故意隐藏构造函数以将Instantiaton限制在特定范围内的情况,或者其他一些更为深奥的情况。

    而且,你不能在命名空间中建立朋友关系,而“友谊”不是在C++中继承的,所以取决于你的单元测试框架,你可能会遇到麻烦。幸运的是,如果您使用的是boost.test,那么这个问题的优雅解决方案是以fixture的形式出现的。

    http://www.boost.org/doc/libs/1_52_0/libs/test/doc/html/utf/user-guide/fixture/per-test-case.html

    您可以使这个fixture成为朋友,并让它实例化您在单元测试函数中使用的所有实例,将它们声明为fixture的静态实例和模块范围。如果您使用的是名称空间,不用担心,您可以只声明名称空间内的fixture和名称空间外的测试用例,然后使用scope resolution操作符来获取静态成员。

    这个 BOOST_FIXTURE_TEST_CASE 宏将负责为您实例化和分解夹具。

        7
  •  4
  •   Pari    9 年前

    很多小时后,我决定这是对那些想要测试其私有功能的人最好的解决方案。这是答案的组合 Max DeLiso 和 MiloÅ¡ .

    如果您正在使用 增压:单元测试 然后有一个简单而优雅的解决方案。

    1. 使用 protected 而不是 private 在你的课上

      /* MyClass.hpp */
      
      class MyClass {
      
      protected:
          int test() {
              return 1;
          }
      };
      
    2. 创建一个 固定装置 :

      /* 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 或添加 朋友 给你们上课!

        8
  •  1
  •   aeh    16 年前

    我认为私有方法不需要单元测试用例。

    如果方法是私有的,则只能在该类中使用。如果您已经使用这个私有方法测试了所有的公共方法,那么就不需要单独测试它,因为它只在这些许多方面使用。