单元测试不可复制的对象

时间:2018-05-27 19:20:50

标签: c++ gmock

我有一个不可复制的怪物基类,我也有一个IView类。 我有一个hobgoblin类继承了怪物和IView, 我有一个控制器,它将一个指向IView的指针作为参数。 基本上我想检查大地精是否爆炸。

我正在使用gmock / gtest

我一直在

Actual function call count doesn't match EXPECT_CALL(h, Explode())...
         Expected: to be called at least once
           Actual: never called - unsatisfied and active

当我使用模拟对象时。我错过了什么?

怪物基地

#ifndef MONSTER_H
#define MONSTER_H

#include <string>

// interface for all monsters
class monster {
public:
    virtual ~monster();

    // forbid copying
    monster(monster const &) = delete;
    monster & operator=(monster const &) = delete;

    void receive_damage(double damage);
    void interact_with_chainsaw();
    std::string name() const;

protected:
    // allow construction for child classes only
    monster();

private:
    virtual void do_receive_damage(double damage) = 0;
    virtual void do_interact_with_chainsaw() = 0;
    virtual std::string do_name() const = 0;
};

#endif // MONSTER_H

IView

#ifndef IVIEW_H
#define IVIEW_H

class IView
{
public:
    virtual void Explode() = 0;
    virtual ~IView(){}
};
#endif // IVIEW_H

大地精

#ifndef HOBGOBLIN_H
#define HOBGOBLIN_H

#include "monster.h"
#include "iview.h"

class hobgoblin : public monster, public IView
{
public:
    hobgoblin();
    void Explode();
    virtual ~hobgoblin();

private:
    void do_receive_damage(double damage) final;
    void do_interact_with_chainsaw() final;
    std::string do_name() const final;

    double health_;
};

#endif // HOBGOBLIN_H

#include "hobgoblin.h"
#include <QDebug>

hobgoblin::hobgoblin() :
    health_(100.0)
{
}

hobgoblin::~hobgoblin()
{
}

void hobgoblin::Explode()
{
    health_ = 0;
    qDebug() << "Health is 0";
}

void hobgoblin::do_receive_damage(double damage)
{
    health_ -= damage;
}

void hobgoblin::do_interact_with_chainsaw()
{
    // imagine horrible, gory things here such as
    // having to deal with a singleton
}

std::string hobgoblin::do_name() const
{
    static std::string const name("Furry hobgoblin of nitwittery +5");
    return name;
}

控制器

#ifndef CONTROLLER_H
#define CONTROLLER_H

#include "iview.h"

class Controller
{
public:
    Controller(IView *view);

    void Explode();

    ~Controller();

private:
    IView *m_View;
};

#endif // CONTROLLER_H

#include "controller.h"
#include <QDebug>

Controller::Controller(IView *view):
    m_View(view)
{

}

void Controller::Explode()
{
    m_View->Explode();
}

Controller::~Controller()
{

}

单元测试

   class mockmonster : public IView
{
public:
    MOCK_METHOD0(Explode,void());

    virtual ~mockmonster(){}
};

TEST(MockMonster,Explode)
{
    // this is not calling explode as expected.
    mockmonster h;
    Controller c(&h);
    c.Explode();

}

TEST(HobGoblin,Explode) 
{
    // this calls explode fine
    hobgoblin h;
    Controller c(&h);
    c.Explode();
} 

1 个答案:

答案 0 :(得分:0)

那么,你的mockmonster函数不应该是虚拟的吗?

根据它的外观,您的IView正在影响Controller的功能。由于IView指向Explode,而IView是非虚拟的,因此会调用Subtitles的版本。

作为旁注,我怀疑你的任何一个课程在这里是不可复制的。使用gmock时,在设置期望/断言时,不可复制的类是有问题的(即,您希望使用特定对象调用函数 - 此对象必须由gmock在内部复制,并且可能会失败)。