Library reference docs
Namespaces
google::cloud::spanner
Classes
Client
Functions
DatabaseAdminClient
Functions
LimitedErrorCountTransactionRerunPolicy
LimitedTimeTransactionRerunPolicy
Structs
Functions
Operators
google::cloud::spanner_admin
Classes
DatabaseAdminClient
Functions
DatabaseAdminConnectionIdempotencyPolicy
DatabaseAdminLimitedErrorCountRetryPolicy
DatabaseAdminLimitedTimeRetryPolicy
InstanceAdminClient
Functions
InstanceAdminConnectionIdempotencyPolicy
InstanceAdminLimitedErrorCountRetryPolicy
InstanceAdminLimitedTimeRetryPolicy
Structs
google::cloud::spanner_admin_mocks
Stay organized with collections Save and categorize content based on your preferences.
In this document we describe how to write unit tests that mock google::cloud::spanner::Client
using Google Mock. This document assumes the reader is familiar with the Google Test and Google Mock frameworks and with the Cloud Spanner C++ Client.
First include the headers for the Cloud Spanner Client, the mocking class, and the Google Mock framework.
#include "google/cloud/spanner/client.h"
#include "google/cloud/spanner/mocks/mock_spanner_connection.h"
#include "google/cloud/spanner/mocks/row.h"
#include <google/protobuf/text_format.h>
#include <gmock/gmock.h>
The example uses a number of aliases to save typing and improve readability:
using ::testing::Return;
namespace spanner = ::google::cloud::spanner;
Create a mocking object for google::cloud::spanner::Connection
:
auto conn = std::make_shared<google::cloud::spanner_mocks::MockConnection>();
We will setup this mock in a second, but first let's look at how it is used to create a google::cloud::spanner::Client
object:
spanner::Client client(conn);
Once the client is created you can make calls on the client as usual:
auto rows = client.ExecuteQuery(
spanner::SqlStatement("SELECT Id, Greeting FROM Greetings"));
And then verify the results meet your expectations:
int count = 0;
using RowType = std::tuple<std::int64_t, std::string>;
for (auto const& row : spanner::StreamOf<RowType>(rows)) {
ASSERT_TRUE(row);
auto expected_id = ++count;
EXPECT_EQ(expected_id, std::get<0>(*row));
EXPECT_EQ("Hello World", std::get<1>(*row));
}
All of this depends on creating a google::cloud::spanner::RowStream
that simulates the stream of results you want. To do so, you need to mock a source that streams google::cloud::spanner::Row
s:
auto source =
std::make_unique<google::cloud::spanner_mocks::MockResultSetSource>();
The source must define the names and types of the columns returned by the query:
auto constexpr kText = R"pb(
row_type: {
fields: {
name: "Id",
type: { code: INT64 }
}
fields: {
name: "Greeting",
type: { code: STRING }
}
})pb";
google::spanner::v1::ResultSetMetadata metadata;
ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString(kText, &metadata));
EXPECT_CALL(*source, Metadata()).WillRepeatedly(Return(metadata));
And then setup the mock to return the results. Note that the results are returned one value at a time, even if a row contains multiple values.
EXPECT_CALL(*source, NextRow())
.WillOnce(Return(google::cloud::spanner_mocks::MakeRow(
{{"Id", spanner::Value(1)},
{"Greeting", spanner::Value("Hello World")}})))
.WillOnce(Return(google::cloud::spanner_mocks::MakeRow(
{{"Id", spanner::Value(2)},
{"Greeting", spanner::Value("Hello World")}})))
Note that the last value in the stream is indicated by an absl::optional without a value:
.WillOnce(Return(spanner::Row()));
Once the source
has been created and its behavior mocked, you mock the behavior for ExecuteQuery
:
EXPECT_CALL(*conn, ExecuteQuery)
.WillOnce([&source](spanner::Connection::SqlParams const&)
-> spanner::RowStream {
return spanner::RowStream(std::move(source));
});
Full Listing
Finally we present the full code for this example:
#include "google/cloud/spanner/client.h"
#include "google/cloud/spanner/mocks/mock_spanner_connection.h"
#include "google/cloud/spanner/mocks/row.h"
#include <google/protobuf/text_format.h>
#include <gmock/gmock.h>
namespace {
using ::testing::Return;
namespace spanner = ::google::cloud::spanner;
TEST(MockSpannerClient, SuccessfulExecuteQuery) {
// Create a mock object to stream the results of a ExecuteQuery.
auto source =
std::make_unique<google::cloud::spanner_mocks::MockResultSetSource>();
// Setup the return type of the ExecuteQuery results:
auto constexpr kText = R"pb(
row_type: {
fields: {
name: "Id",
type: { code: INT64 }
}
fields: {
name: "Greeting",
type: { code: STRING }
}
})pb";
google::spanner::v1::ResultSetMetadata metadata;
ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString(kText, &metadata));
EXPECT_CALL(*source, Metadata()).WillRepeatedly(Return(metadata));
// Setup the mock source to return some values:
EXPECT_CALL(*source, NextRow())
.WillOnce(Return(google::cloud::spanner_mocks::MakeRow(
{{"Id", spanner::Value(1)},
{"Greeting", spanner::Value("Hello World")}})))
.WillOnce(Return(google::cloud::spanner_mocks::MakeRow(
{{"Id", spanner::Value(2)},
{"Greeting", spanner::Value("Hello World")}})))
.WillOnce(Return(spanner::Row()));
// Create a mock for `spanner::Connection`:
auto conn = std::make_shared<google::cloud::spanner_mocks::MockConnection>();
// Setup the connection mock to return the results previously setup:
EXPECT_CALL(*conn, ExecuteQuery)
.WillOnce([&source](spanner::Connection::SqlParams const&)
-> spanner::RowStream {
return spanner::RowStream(std::move(source));
});
// Create a client with the mocked connection:
spanner::Client client(conn);
// Make the request and verify the expected results:
auto rows = client.ExecuteQuery(
spanner::SqlStatement("SELECT Id, Greeting FROM Greetings"));
int count = 0;
using RowType = std::tuple<std::int64_t, std::string>;
for (auto const& row : spanner::StreamOf<RowType>(rows)) {
ASSERT_TRUE(row);
auto expected_id = ++count;
EXPECT_EQ(expected_id, std::get<0>(*row));
EXPECT_EQ("Hello World", std::get<1>(*row));
}
}
} // namespace
Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. For details, see the Google Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2025-08-14 UTC.
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Hard to understand","hardToUnderstand","thumb-down"],["Incorrect information or sample code","incorrectInformationOrSampleCode","thumb-down"],["Missing the information/samples I need","missingTheInformationSamplesINeed","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2025-08-14 UTC."],[],[]]
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4