我试图使用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
只是不会导致测试失败而不关心方法begin
是否被调用。它总是过去!
更新:
这似乎与extern
无关,在全局区域声明一个HardwareSerial
类型的新变量会导致完全相同的问题,将其移到类中可以消除问题。
TL,DR:倾向于创建模拟对象作为测试用例的成员。
长解释:
关于如何使用它们,请参阅这里的Google Mock介绍,特别是最后一点:
当mock被销毁时, gMock会自动检查是否全部对它的期望已得到满足。
(粗体由我)。关键是,当mock对象被析构时,EXPECT_CALL
是根据实际调用进行计算的(这在c++中依赖于RAII是很常见的)。这样的全局对象在程序的main
方法退出时被销毁,因此在测试用例结束后您不会看到任何错误。当在测试套件中定义mock对象时,它将在测试开始时创建,并在测试结束时销毁(准确地说:mock在测试用例的变量中构造,并在调用测试用例的变量时销毁)。如果您使用TEST_F
,这是为给定测试套件中的每个测试用例完成的。