c++ - 单元测试对实例变量函数的调用

标签 c++ unit-testing misra

我有一些类似于下面给出的示例的 C++ 代码。我想编写一个单元测试来验证 mFlashLamp.trigger 是否被调用了五次。 但是,到目前为止,我还没有想出一个好的方法来做到这一点。

我有以下限制: 符合 Misra/GoogleTest/GoogleMock

include <iostream>

class FlashLamp
{
public:
    virtual void trigger(){
        std::cout << "Trigger FlashLamp" << std::endl;
    }
};

class Spectrometer
{
public:
    FlashLamp mFlashLamp;

    void foo(){
        for( int i=0; i<5; i++ ){
            mFlashLamp.trigger();
        }
    }

};

int main(){
    Spectrometer S;
    S.foo();
    return 0;
}

有没有人有好的、干净的单元测试解决方案。 我能想到的一种解决方案是

class Spectrometer
{
public:
    FlashLamp mFlashLamp;
    FlashLamp* pFlashLamp;
}

有一个额外的指向实例变量的指针,并使用它来访问触发器。但这将意味着一些代码膨胀,因为它需要对每个取消引用进行空指针检查。 有没有人有更好的解决方案的想法。

附言: 我真的想想出一个好标题,但做不到。如果有人有任何改进,请随时对其进行编辑。

最佳答案

单元测试中惯用的方法是使用接口(interface)模拟类:

#include <iostream>

// The interface definition
struct IFlashLamp {
    virtual ~IFlashLamp() {}
    virtual void trigger() = 0;
};

class FlashLamp : public IFlashLamp 
{
public:
    virtual void trigger() override {
        std::cout << "Trigger FlashLamp" << std::endl;
    }
};

class Spectrometer
{
public:
    IFlashLamp& mFlashLamp;

    Spectrometer(IFlashlamp& flashLamp) : mFlashLamp(flashLamp) {}
    void foo(){
        for( int i=0; i<5; i++ ){
            mFlashLamp.trigger();
        }
    }

};

您将使用模拟类实现该接口(interface),该模拟类允许您检查对接口(interface)调用的预期:

class FlashLampMock : public IFlashlamp {
    int triggerCallCounter;
public:
    FlashLampMock() : triggerCallCounter(0) {}
    virtual void trigger() override {
        ++triggerCallCounter;
    }
    int getTriggerCallCounter() const { return triggerCallCounter; }
};

这就是单元测试:

int main(){
    FlashLampMock flashLampMock;
    Spectrometer S(FlashLampMock);
    S.foo();
    assert(flashLampMock.getTriggerCallCounter() == 5);
    return 0;
}

关于c++ - 单元测试对实例变量函数的调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47443981/

相关文章:

C++ lambda 表达式 : captured pointer to STL container changing address after pop?

c++ - 我的程序没有在屏幕上显示字符

c++ - 如何使用循环显示菜单并重新提示输入?

java - 在 Java 中进行单元测试时如何强制调用 SQLException?

c++ - 静态函数模板和 MISRA C++

c - MISRA C 规则 15.5 由于多次使用具有 return 的定义而在函数中多次退出

c++ - 如何在 C 宏中连接变量字符串和文字字符串?

javascript - 为什么我的 jest.mock 中的 Promisereject() 会转到 then() 而不是 catch()?

android - 如何在 Android 测试中正确模拟 HttpGet 调用

c - 如何编写与MISRA:2012完全兼容的memcpy函数?