通过 gtest 和 gmock 定义和使用 MOCK_METHOD

Define and use MOCK_METHOD with gtest and gmock

我是 googletest/googlemock 的新手,我有以下问题:

第一个问题:我有这个 DatabaseClient class,它有一个我想模拟的方法 query_items。我找不到执行此操作的语法。这是我的尝试:

class DatabaseClient {
  public:
    // constructors
    DatabaseClient();
    DatabaseClient(std::string base_url, std::string master_key);

    // destructor
    ~DatabaseClient();

    // properties
    some properties

    // methods
    // last parameter is optional with default value NULL
    CURLcode query_items(std::string databaseId, std::string containerId, std::string query, size_t (*p_callback_function)(void*, size_t, size_t, std::string*) = NULL);
};

class MockDatabaseClient {
    public:
        MOCK_METHOD(CURLcode, query_items, (std::string databaseId, std::string containerId, std::string query, size_t (*p_callback_function)(void*, size_t, size_t, std::string*));
        };

MOCK_METHOD有编译错误,请问如何正确编写?

第二个问题: 数据库客户端用于我要测试的测试服务class:这是我要测试的方法的示例:

#include "db/DatabaseClient.hpp"
#include "db/LibcurlCallbacks.hpp"

TestService::create() {
    DatabaseClient* databaseClient = new DatabaseClient();
    std::string body = "some query"
    try {
       auto respone = databaseClient->query_items(this->databaseName, this->containerName, body, \
            LibcurlCallbacks::CallbackFunctionOnCreate);

        return SomeObject;
    }

如何在我的测试中模拟 databaseClient->query_items 因为我不想在 运行 测试时访问数据库。

这是我开始的基本测试:

#include <gtest/gtest.h>
#include "gmock/gmock.h" 

#include "../src/service/TestService.hpp"
#include "../src/db/DatabaseClient.hpp"
#include "../src/db/LibcurlCallbacks.hpp"


using ::testing::AtLeast;
TEST(HelloTest, BasicAssertions) {
  // Expect two strings not to be equal.
    MockCosmosClient cosmosClient;

    //EXPECT_CALL(cosmosClient, query_items("test", "test", "test", LibcurlCallbacks::CallbackFunctionOnDestinationCreate))

    TestService ds;
    auto response = ds.create();
  EXPECT_STRNE(response, "some string");

}

感谢任何帮助!

您需要以某种方式告诉您的 TestService class 使用模拟对象而不是真实对象。

目前您在 create() 中实例化 DatabaseClient:

TestService::create() {
    DatabaseClient* databaseClient = new DatabaseClient();
    //...
    }

您应该告诉它使用 MockDatabaseClient。这可以通过多种方式完成:

使用依赖注入:

创建一个名为 DatabaseClientInterface 的具有虚函数的抽象 class 接口,然后让您的 MockDatabaseClientDatabaseClient 继承并实现该 class。

然后不是在TestService::create中实例化databaseClient,而是在TestService中有一个DatabaseClientInterface*类型的成员变量,它可以在[=13=的构造函数中初始化] 通过 MockDatabaseClient 用于测试或 DatabaseClient 用于生产的对象。

在你的测试中你应该调用:

TEST(HelloTest, BasicAssertions) {
  MockDatabaseClient mock_client;
  TestService ds(&mock_client);
  //...

将您的 class 模板化:

使 TestService 成为模板 class,它根据模板变量创建 databaseClient 对象。像这样:

template <typename T>
class TestService
{
 //...
 create() {
    T* databaseClient = new DatabaseClient();
    //...
    }

};

现在用 MockDatabaseClient.

测试实例化 TestService

请参阅 GMock 文档或 here for an example of the first method and here 以获取第二种方法的示例。

编译问题

至于 MOCK_METHOD 的编译问题,请注意宏是有限的,预处理器会因在宏参数中看到 , 而感到困惑。我认为你正在点击 this problem.