(Contributed by JonWray on 2008/3/11; updated by ZhanyongWan later.)
I‘m testing a C++ frontend that calls several different backends, but I’ll just include an example for one to keep this relatively short. This example is mocking a CacheServer
backend. An explanation follows the code.
using ::testing::_; using ::testing::BeDone; using ::testing::EqualsProto; using ::testing::RespondWith; class MockCacheServer : public CacheServerRPC { public: MockCacheServer(HTTPServer *hs) { rpc2::EnableRPC2(this, rpc2::ServiceParameters()); CacheServerRPC::ExportService(hs); ON_CALL(*this, Insert).WillByDefault(BeDone()); ON_CALL(*this, Lookup).WillByDefault(BeDone()); } MOCK_METHOD(void, Insert, (RPC*, const CacheInsertCommandProto*, CacheInsertResultsProto*, Closure*), (override)); MOCK_METHOD(void, Lookup, (RPC*, const CacheLookupCommandProto*, CacheLookupResultsProto*, Closure*), (override)); }; ... // This is in the test fixture. MockCacheServer cacheserver_; ... // Now the code that uses it: CacheLookupCommandProto command; // Init command CacheLookupResultsProto results; // Init results EXPECT_CALL(cacheserver_, Lookup(_, EqualsProto(command), _, _)) .WillOnce(RespondWith(results));
In the success case, the command matches the EXPECT_CALL
, so results is set and the callback is called.
In the failure case, the command matches the default ON_CALL
, the results are not set, and the done closure is called (don't want the test to hang).
So it‘s a bit ugly, but given that I need to mock five backends, I think it’s better than doing this manually. The best part is the nicely formatted error messages when the expected call is incorrect. Once all this scaffolding is in place, it's easy to churn out test suites.
Discussions:
StubbySimulator
by Mike Bland might also be useful: google3/testing/lib/net/rpc/stubby_simulator.h.RPC::OK
. This sort of approach to splitting RPC calls into separate objects from ControlFlows was first explored in TotT Episode 46.