#c #unit-testing #googletest #googlemock
#c #модульное тестирование #googletest #googlemock
Вопрос:
Я пытаюсь использовать google test
и google mock
протестировать свой простой класс C . Мой макет класса выглядит так:
#pragma once
#include "base_classes/_HardwareSerial.h"
#include "gmock/gmock.h"
class HardwareSerial : public _HardwareSerial
{
public:
HardwareSerial() = default;
MOCK_METHOD(void, begin, (unsigned long baud_rate), (override));
MOCK_METHOD(void, end, (), (override));
MOCK_METHOD(void, print, (const __FlashStringHelper *in_flash_str), (override));
MOCK_METHOD(void, print, (const char *str), (override));
};
extern HardwareSerial Serial;
Теперь я использую этот макет класса в своем тестовом файле cpp:
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "HardwareSerial.h"
using ::testing::_;
HardwareSerial Serial; // <<< Putting this here does NOT work. The test passes whatever if the function has never been called called 10000 times. The test just passes.. This is the problem I have.
HardwareSerial AnotherNewSerial; // <<< Does NOT work.
class Test_Class: public ::testing::Test
{
protected:
HardwareSerial Serial; // <<< Putting this here makes the test working, but of course if anything relies on the global extern variable will cause compilation error.
HardwareSerial AnotherNewSerial; // <<< Works.
void SetUp() override
{
}
void TearDown() override
{
}
};
TEST_F(Test_Class, MYTEST)
{
EXPECT_CALL(Serial, begin(_))
.Times(10);
}
Определение внешней HardwareSerial Serial
переменной в глобальной области в моем тесте приводит к тому, что тест проходит все, что я делаю с этой переменной. Так что мой EXPECT_CALL
just не приводит к сбою теста, не заботясь о том, был ли begin
вызван метод или нет. Это просто всегда проходит!
Однако перемещение объявления в класс заставляет тест работать так, как ожидалось. Однако я не могу полагаться на это, потому что у меня есть другие компоненты, которые полагаются на эту глобальную внешнюю переменную. И очень интересно узнать, что здесь происходит и как я могу это исправить?
Обновить:
Кажется, это не имеет ничего общего с extern
тем, что объявление новой переменной типа HardwareSerial
в глобальной области вызывает точно такую же проблему, а перемещение ее в классы устраняет проблему.
Комментарии:
1. Я нигде не нашел его официально, но, похоже, создание экземпляра type
Google Mocks
до инициализации Google test / mock каким-то образом не работает. По-видимому, именно по этой причине у меня возникла проблема, упомянутая выше.
Ответ №1:
TL, DR: как правило, создают фиктивные объекты в качестве членов тестового примера.
Длинное объяснение:
Пожалуйста, ознакомьтесь с вводной частью Google Mock здесь о том, как их использовать, особенно в последнем пункте:
Когда макет уничтожается, gMock автоматически проверяет, были ли удовлетворены все ожидания от него.
(выделено мной жирным шрифтом). Ключевым моментом является то, что EXPECT_CALL
s вычисляются по фактическим вызовам, когда макет объекта уничтожается (это обычная вещь в C , зависящая от RAII). Подобный глобальный объект уничтожается при завершении main
работы метода программы, поэтому вы не увидите никаких ошибок после завершения тестового примера. Когда макет объекта определен в наборе тестов, он будет создан в начале теста и уничтожен по окончании теста (если быть точным: макет создается в ctor тестового набора и уничтожается при вызове dtor тестового набора. Это делается для каждого тестового примера в данном наборе тестов, если вы используете TEST_F
).