Юнит тест неокопируемого объекта - PullRequest
0 голосов
/ 27 мая 2018

У меня есть некопируемый базовый класс монстров, у меня также есть класс 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

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 голосов
/ 27 мая 2018

Ну, разве ваша Explode функция не должна быть виртуальной?

Похоже, ваш mockmonster выполняет функцию IView.Поскольку Controller принимает указатель на IView, а Explode не является виртуальным, он вызовет версию IView.


В качестве примечания, я сомневаюсь, еслилюбой из ваших классов здесь не подлежит копированию.При использовании gmock не копируемые классы проблематичны при настройке ожиданий / утверждений (т. Е. Вы ожидаете, что функция будет вызываться с определенным объектом - этот объект должен был бы быть скопирован изнутри gmock, и это может привести к ошибке).

...