Как вы создаете Mock Objects с помощью gMock? - PullRequest
2 голосов
/ 04 марта 2020

Итак, я пытаюсь научиться писать модульные тесты и наткнулся на проблему, что я не понимаю, как создавать фиктивные объекты. Вот мой пример: у меня есть этот класс:

class FooChild
{
public:
    void doThis();
    bool doThat(int n, double x);
};

И это метод в другом классе, который я хочу проверить:

#include "FooFighter.h"
#include "FooChild.h"

void FooFighter::doSomething()
{
    FooChild fooChild;
    fooChild.doThis();
    fooChild.doThat(4, 5);
}

Я хочу проверить вещи, например, если они вызвали метод и сколько раз. В документальном фильме о насмешках Google говорится, что только абстрактные классы с виртуальными методами могут быть смоделированы. Вот почему я попытался создать родительский класс FooChild, например:

class Foo
{
public:
    virtual void doThis() = 0;
    virtual bool doThat(int n, double x) = 0;
};

, а затем создать фиктивный класс Foo следующим образом:

#include "gmock/gmock.h"

class MockFoo : public Foo
{
public:
    MOCK_METHOD(void, doThis, (), (override));
    MOCK_METHOD(bool, doThat, (int n, double x), (override));
};

Затем я попытался написать Тест на doSomething:

TEST_F(FooFighterTest, doSomethingTest)
{
    MockFoo mock_foo
    mock_foo.doThis()
        .Times(1);
}

Ясно, что это не работает, и у меня есть ощущение, что я совершенно не понял, как работают насмешки, но я просто не могу найти хорошее и простое объяснение того, как создать издевается. Любая помощь или совет будут великолепны. Также мой подход к тестированию таких пустых функций может быть совершенно неверным, поэтому любые советы по тестированию функций, которые ничего не возвращают, были бы также хороши.

Ответы [ 2 ]

1 голос
/ 04 марта 2020

Ваш пример не слишком далек от работы. Возможно, вам будет полезно прочитать документ gMock for Dummies . Это дает хороший обзор основ.

По существу, макеты позволяют вам устанавливать на них ожидания и проверять их соответствие. Вы также можете делать такие вещи, как управление возвращаемыми значениями смоделированных методов. Поддельные методы должны быть виртуальными, но не требуется, чтобы они были абстрактными.

class FooChild
{
public:
    virtual void doThis() {}
    virtual bool doThat(int n, double x) { return false; }
};

class MockFooChild : public FooChild
{
public:
    MOCK_METHOD(void, doThis, (), (override));
    MOCK_METHOD(bool, doThat, (int n, double x), (override));
};

Самая большая проблема в вашем примере заключается в том, что FooFighter::doSomething использует конкретный (реальный) класс FooChild. Вам понадобится способ заменить конкретный класс фиктивным классом (используя некоторую форму внедрения зависимости). Вот простой пример:

class FooFighter
{
public:
    void doSomething(FooChild &fooChild)
    {
        fooChild.doThis();
        fooChild.doThat(4, 5);
    }
};

Теперь вы можете проверить, что FooFighter::doSomething делает то, что ожидается:

TEST(FooFighterTest, doSomethingTest)
{
    MockFooChild mockFooChild;
    FooFighter fooFighter;

    // doThis() must be called exactly 1 time.
    EXPECT_CALL(mockFooChild, doThis).Times(Exactly(1));

    // doThat() must be called exactly 1 time with parameters 4,5
    EXPECT_CALL(mockFooChild, doThat(4,5)).Times(Exactly(1));

    fooFighter.doSomething(mockFooChild);
}
0 голосов
/ 04 марта 2020

Вы упускаете довольно много вещей, если не помещаете их сюда. Внимательно читайте документацию googletests и, в частности, mocks . Вот как я обычно определяю макеты:

#include <gmock/gmock.h>
#include "Foo.hpp"

class MockFoo : public Foo {
 public:
    MOCK_METHOD0(doThis, void());
    MOCK_METHOD2(doThat, bool(int n, double x));
};

Вам нужно записать количество аргументов методов после выражения MOCK_METHOD, затем тип возврата и между скобками типы аргументов. Если вы не хотите беспокоиться об этом, используйте этот красивый генератор , который находится в библиотеке.

Тогда в самих тестах вы определяете поведение макета, то есть Суть в том, что вы можете сделать общее определение для всех тестов или изменить его для работы по-другому.

Я думаю, что не имеет смысла писать полный пример, потому что у вас есть в учебники действительно хорошие и простые , так что проверьте это.

...