【问题标题】:Unit test a variable for both true and false单元测试一个变量的真假
【发布时间】:2016-05-20 12:25:17
【问题描述】:

我正在这里使用 googletest/googlemock 编写 C++ 生产代码。在使用 A.cpp 中的一个函数时,我偶然发现了这个想法:

bool A::process_(false);

bool A::process()
{
    if ( !process_ ){
        process_ = true;
    }
return process_;
}

标头包含的位置:

protected:
    static bool process_;
public:
    static bool process();

我被困在一种方式中,我只能测试函数的预期输出 true 或 false 输入,如下所示:

TEST(ATest, processVal){

    A a;
    EXPECT_TRUE(a.process());

}

有没有办法测试函数,以便通过 process_*true**false* 值?这样测试就涵盖了两者的决定。 我在考虑模拟,以便它可以期待对 true 和 false 的调用,但因为它不是类成员中的函数,我猜你不能对 process_ 进行模拟? 如果可以,如何模拟变量?

注意:我使用的是 linux 和 gcc :) 谢谢!

【问题讨论】:

  • 您是否正在寻找从测试中修改process_ 的方法?
  • 我当前的目标:在不更改任何生产代码的情况下,在函数“process()”中为“if 语句”做出正确和错误的决定。换句话说,在不使用 googletest 更改生产代码的情况下,测试/涵盖 true 和 false 的 if 语句,而不是仅 false。
  • 检查我的答案,它将允许测试代码修改_process,而无需在生产代码中进行任何更改。

标签: c++ linux unit-testing googletest


【解决方案1】:
  • 解决方案 1: 从测试中访问任何 protected 属性/方法 无需修改生产代码

即使受到保护,您也可以轻松修改_process,只需这样做:

class SubA : public A
{
public:
    void setProcess( bool val ) { process_ = val; }
};

A a;
SubA* pA = (SubA*) &a;
pA->setProcess( false );

这会很好用而且很安全。即使您将A* 强制转换为SubA* 这并不是真正有效的,它也将作为内存中的SubA 对象与A 对象相同(因为SubA 没有声明任何额外的属性)。

这只是因为process_protected,所以你创建了一个派生类SubA 并使用它,因为编译器将允许这个子类访问受保护的东西。

  • 解决方案2:在不修改生产代码的情况下从测试中访问任何protected 甚至private属性/方法

现在,如果 process_private,这将不起作用...但是,private/protected 仅由编译器管理...属性在内存中,您可以访问它们即使你没有“被允许”。

它很丑,但效果很好:

#define protected public
#define private public
#include "A.h"
#undef private
#undef protected

{
    A a;
    a._process = false;
}

这个 hack 可以很容易地从您的测试程序中访问任何 private/protected 属性/函数。

【讨论】:

  • 很好的解释。谢谢你。据我了解,您的方法要求我删除 'bool A::process_(false);'在我的 .cpp 中添加一行并将其替换为“SubA”类(包括其下方的代码),这是真的吗?然后在测试程序 ATest.cpp 中,我只需要添加“#define protected public”(包括它下面的代码)并操纵我的 _process? 的值。有没有办法让我可以在测试本身中修改“_process”而无需更改生产代码,以便在“if 语句”的函数“process()”中做出正确和错误的决定。 @jpo38
  • 不,我提出了两种不同的方法来访问和修改_process。在这两种情况下,您都不需要修改产品。第一种方法 (SubA),您从测试代码中声明 SubA 类,然后将 ̀A` 对象转换为 SubA。第二种方法,您只需在测试代码中添加 #define 语句即可完成,_process 可以从您的测试代码中访问。
  • 谢谢@jpo38,我会试试这个并在这里发布结果。
【解决方案2】:

声明A 的子类。由于process_protected,因此您可以在运行测试之前使用A to set it totrueorfalse 的子类。

【讨论】:

  • 嗨,Sam,我正在尝试实现一个成功的测试,其中在函数 process() 中做出正确和错误的决定。在我的测试程序中,我想操纵 process_ 以便 if 语句接收真假输入,而不仅仅是假。
猜你喜欢
  • 1970-01-01
  • 2017-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多