如何在 C++ 中对受保护的方法进行单元测试?

Posted

技术标签:

【中文标题】如何在 C++ 中对受保护的方法进行单元测试?【英文标题】:How do I unit test a protected method in C++? 【发布时间】:2010-11-10 18:54:09 【问题描述】:

在 Java 中,我要么在与被测类相同的包中创建测试类,要么创建一个匿名子类,在我的测试类中公开我需要的方法,但这些方法在 C++ 中都不可用.

我正在使用 NUnit 测试一个非托管 C++ 类。

【问题讨论】:

您在使用 GenTestAsm-codeproject.com/KB/applications/GenTestAsmBase.aspx 吗?或者您还如何从 NUUnit (.NET) 运行非托管 C++ 代码? 【参考方案1】:

假设您指的是可公开访问的类的受保护方法:

在测试代码中,定义被测类的派生类(直接或从其派生类之一)。为受保护的成员添加访问器,或在派生类中执行测试。 “受保护的”访问控制在 C++ 中确实不是很可怕:它不需要基类的合作来“破解”它。所以最好不要在基类中引入任何“测试代码”,甚至是友元声明:

// in realclass.h
class RealClass 
    protected:
    int foo(int a)  return a+1; 
;

// in test code
#include "realclass.h"
class Test : public RealClass 
    public:
    int wrapfoo(int a)  return foo(a); 
    void testfoo(int input, int expected) 
        assert(foo(input) == expected);
    
;

Test blah;
assert(blah.wrapfoo(1) == 2);
blah.testfoo(E_TO_THE_I_PI, 0);

【讨论】:

这是解决这个问题的真正面向对象的解决方案。继承的存在是有原因的!【参考方案2】:

您也可以使用 using 关键字来公开公共块(使用 .

// in realclass.h
class RealClass 
    protected:
    int foo(int a)  return a+1; 
    int foo(string a)  return a.length();  // Overload works too
    template<class T> int foo(const T& a)  return 1;  // Templates work too
;

// in test code
#include "realclass.h"
class RealClassExposed : public RealClass 
    public:
        using RealClass::foo;
;

RealClassExposed blah;
assert(blah.foo(1) == 2);
assert(blah.foo("test") == 4);
assert(blah.foo(blah) == 1);

见:http://en.cppreference.com/w/cpp/language/using_declaration

【讨论】:

【参考方案3】:

我使用CxxTest 并让 CxxTest 从包含受保护成员函数的类派生。如果您仍在寻找您最喜欢的 C++ 单元测试框架,请查看this article。

【讨论】:

【参考方案4】:

声明一个朋友类 MyClass_UnitTest;在你的 MyClass 中。然后,您可以在单元测试程序的其他地方定义 MyClass_UnitTest ,它可以完全访问 MyClass 内部,但您不必在发布应用程序中提供实现。 请参阅 CppUnit 文档,了解如何完成此操作的一个很好的示例。

【讨论】:

朋友班不是你的朋友。 那么没有什么是你的朋友。每种语言的每个功能都可能被误用和滥用。仅仅因为白痴滥用该功能并不意味着我不应该将其用于正确的目的。 同意,但有些功能比其他功能更容易被滥用。我经常看到用于规避封装的友元函数。【参考方案5】:

在 C++ 中有一个使用#define 的简单解决方案。只需像这样包装“ClassUnderTest”的包含:

#define protected public
 #define private   public
    #include <ClassUnderTest.hpp>
 #undef protected
#undef private

Credit goes to this article and RonFox

【讨论】:

响应 -1... 我知道在“理论”中您应该测试公共接口。然而,在开发周期的实践中,这可能是一个非常宝贵的技巧。我的建议......明智地使用它。【参考方案6】:

考虑一个公共的、可能是静态的“单元测试”函数。

丑陋,但比我能想到的使用宏或朋友之类的替代品要好。

【讨论】:

以上是关于如何在 C++ 中对受保护的方法进行单元测试?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Excel 2013 中对受保护的工作表启用排序

受保护插槽的单元测试[关闭]

如何在 Typescript 中对私有方法进行单元测试

如何在 java 中对这个方法进行单元测试?

如何在Typescript中对私有方法进行单元测试

如何在验证方法 nuxtjs vuejs jest 中对代码进行单元测试