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

时间:2017-11-22 21:14:55

标签: 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;
}

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

PS: 我真的试图想出一个好头衔,但不能。如果有人有任何改进,请随时编辑它。

1 个答案:

答案 0 :(得分:1)

单元测试中的惯用方法是使用 interfaces Mock Classes

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

};

您将使用模拟类实现接口,允许您检查有关接口调用的期望:

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