单元测试不可复制的对象

Unit test noncopyable object

本文关键字:对象 可复制 单元测试      更新时间:2023-10-16

我有一个不可复制的怪物基类,我还有一个IView类。 我有一个从两个怪物和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

、四

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

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

从外观上看,你的mockmonster正在遮蔽IView的功能。由于Controller是指向IView的指针,而Explode是非虚拟的,它将调用IView的版本。


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