by Zhanyong Wan, Software Engineer
Life is unfair. You work every bit as hard as Joe the Java programmer next to you. Yet as a C++ programmer, you don't get to play with all the fancy programming tools Joe takes for granted.
In particular, without a good mocking framework, mock objects in C++ have to be rolled by hand. Boy, is that tedious! (Not to mention how error-prone it is.) Why should you endure this?
Dread no more. Google Mock is finally here to help! It's a Google-originated open-source framework for creating and using C++ mocks . Inspired by jMock and EasyMock, Google Mock is easy to use, yet flexible and extensible . All you need to get started is the ability to count from 0 to 10 and use an editor.
Think you can do it? Let's try this simple example: you have a ShoppingCart class that gets the tax rate from a server, and you want to test that it remembers to disconnect from the server even when the server has generated an error. It's easy to write the test using a mock tax server, which implements this interface:
class TaxServer { // Returns the tax rate of a location // (by postal code) or -1 on error. virtual double FetchTaxRate( const string& postal_code) = 0; virtual void CloseConnection() = 0; };
Here's how you mock it and use the mock server to verify the expected behavior of ShoppingCart :
class MockTaxServer : public TaxServer { // #1 MOCK_METHOD1 (FetchTaxRate, double(const string&)); MOCK_METHOD0 (CloseConnection, void()); }; TEST(ShoppingCartTest, StillCallsCloseIfServerErrorOccurs) { MockTaxServer mock_taxserver; // #2 EXPECT_CALL (mock_taxserver, FetchTaxRate(_)) .WillOnce (Return (-1)); // #3 EXPECT_CALL (mock_taxserver, CloseConnection()); ShoppingCart cart(&mock_taxserver); // #4 cart.CalculateTax(); // Calls FetchTaxRate() // and CloseConnection(). } // #5
Derive the mock class from the interface. For each virtual method, count how many arguments it has, name the result n , and define it using MOCK_METHODn , whose arguments are the name and type of the method.
Create an instance of the mock class. It will be used where you would normally use a real object.
Set expectations on the mock object (How will it be used? What will it do?). For example, the first EXPECT_CALL says that FetchTaxRate() will be called and will return an error. The underscore (_) is a matcher that says the argument can be anything. Google Mock has many matchers you can use to precisely specify what the argument should be like. You can also define your own matcher or use an exact value.
Exercise code that uses the mock object. You'll get an error immediately if a mock method is called more times than expected or with the wrong arguments.
When the mock object is destroyed, it checks that all expectations on it have been satisfied.
You can also use Google Mock for rapid prototyping – and get a better design. To find out more, visit the project homepage at http://code.google.com/p/googlemock/ . Now, be the first one on your block to use Google Mock and prepare to be envied. Did I say life is unfair?
Remember to download this episode and post it in your office!Toilet-Friendly Version
hello, thanks for your introduction. But can you draw a draft of ShoppingCart class. Because I am novice of C++, I am struggling with the declaration stuff.. ^^;;
ReplyDeleteI can't imagine the look like of the class.
Thx.
cheol
Firts time with Gmock framework, I am trying to use simple example of google mock. Is someone can tell me what I am doing wrong here ?
ReplyDeleteThanks.
Here is my code in one file Test.h
class myInterface
{
public:
virtual ~myInterface(){}
virtual bool isReady(void) = 0;
};
class ConcreteImpl : public myInterface
{
public:
bool isReady(){return true;};
};
class MockInterface : public myInterface
{
public:
MOCK_METHOD0(isReady, bool());
};
Here my Test.cpp file using BOOST LIB
class TestDriver
{
public:
TestDriver()
{
BOOST_TEST_MESSAGE("execute TestSetup constructor");
};
~TestDriver()
{
BOOST_TEST_MESSAGE("execute TestSetup destructor");
};
MockInterface mxDriver; // if I comment out this line, it is compiling.
};
when I compile, I am getting an error :
tests\test_src\build/googletest-src/googletest/src/gtest-port.cc:275: multiple definition of `testing::internal::Mutex::Lock()'
CMakeFiles/Test.dir/test_src/DriverTest.cpp.obj:C:tests\test_src\build/googletest-src/googletest/include/gtest/internal/gtest-port.h:2262: first defined here
collect2.exe: error: ld returned 1 exit status
But things are working if I do not create an instance of my mock class !