Reputation: 607
I am new to googletest/googlemock and I have following questions:
First question: I have this DatabaseClient class which has a method query_items which I want to mock. I`m unable to find the syntax to do it. Here is my attempt:
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*));
};
The MOCK_METHOD has compile errors, can you help in how to write it correctly?
SECOND Question: The Database client is used in a test service class which I want to test: Here is the sample of the method which I want to test:
#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;
}
How can I mock the databaseClient->query_items in my test because I do not want to hit the database when running tests.
Here is the basic test I started:
#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");
}
Any help is appreciated!
Upvotes: 2
Views: 8218
Reputation: 7556
Somehow you need to tell your TestService
class to use the mock object instead of the real object.
Currently you instantiate the DatabaseClient
in create()
:
TestService::create() {
DatabaseClient* databaseClient = new DatabaseClient();
//...
}
You should tell it to use MockDatabaseClient
instead. This can be done in several ways:
Create an abstract class interface called DatabaseClientInterface
that has virtual functions, then have your MockDatabaseClient
and DatabaseClient
inherit and implement that class.
Then rather than instantiating databaseClient
in TestService::create
, have a member variable in TestService
of type DatabaseClientInterface*
which can be initialized in the constructor of TestService
by an object of either MockDatabaseClient
for testing or DatabaseClient
for production.
In your test you should then call:
TEST(HelloTest, BasicAssertions) {
MockDatabaseClient mock_client;
TestService ds(&mock_client);
//...
Make TestService
a template class which creates the databaseClient
object based on the template variable. Something like this:
template <typename T>
class TestService
{
//...
create() {
T* databaseClient = new DatabaseClient();
//...
}
};
Now for testing instantiate TestService
with MockDatabaseClient
.
See GMock documentations or here for an example of the first method and here for an example of the second method.
Compile issues
As for the compile issues with MOCK_METHOD
, note that macros are limited and the preprocessor gets confused by seeing ,
in a macro parameter. I think you are hitting this problem.
Upvotes: 2