Some times we may use google mock as a test double. Here is another string calculator feature. The difference from simple string calculator is that "Then The result should be " has been changed to " Then The result shall be informed". The calculaor may inform sum to a screen or GUI.
Feature: String calculator using mock object
Client can get sum of numbers by inputting a string.
Scenario Outline: A separator can be +, comma or semicolon.
A separator could be either +, comma or semicolon. But it is not allowed to combinate different separators.
When Input <Numbers>
Then The result <Sum> shall be informed
Examples:
|Numbers |Sum|
|1 + 2 + 3|6 |
|4, 5, 6 |15 |
|7; 8; 9 |24 |
|1, 2; 3 |0 |
Let's assume that the calculator will inform the sum to following IDisplay interface.
class IDisplay
{
public:
~IDisplay(){}
virtual void Sum(int sum) = 0;
};
In the implementation of scenario we may use following google mock object.
#include "IDisplay.h"
using namespace testing;
class MockDisplay : public IDisplay
{
public:
MOCK_METHOD1(Sum, void(int sum));
void ExpectSum(int sum)
{
EXPECT_CALL(*this, Sum(sum));
}
};
The calling sequence of our executable specification is .
Sure, this implementation will fail. The problem is that google mock requires that expectations of a mock object must be set before a function of the mock object called. In other words, MockDisplay::ExpectSum must be called before StringCalculator::CalculateSum being called. This is only a technique issue, it is differnt from the normal readable specification. It will be unreadable specification if we rewrite the feature as following to pass our test program, i.e. put Then step before the When step.
Feature: String calculator using mock object
Client can get sum of numbers by inputting a string.
Scenario Outline: A separator can be +, comma or semicolon.
A separator could be either +, comma or semicolon. But it is not allowed to combinate different separators.
Then The result <Sum> shall be informed
When Input <Numbers>
Examples:
|Numbers |Sum|
|1 + 2 + 3|6 |
|4, 5, 6 |15 |
|7; 8; 9 |24 |
|1, 2; 3 |0 |
Our test program will all succeed if we update our feature as following, where Cucumber/C++'s [[mock]] attribute is used. Steps with [[mock]] attribute will be executed before hand when running executable specification. It may affect readability of specification a little bit, but we can implement our steps in a straight forward way.
Feature: String calculator using mock object
Client can get sum of numbers by inputting a string.
Scenario Outline: A separator can be +, comma or semicolon.
A separator could be either +, comma or semicolon. But it is not allowed to combinate different separators.
When Input <Numbers>
Then The result <Sum> shall be informed[[mock]]
Examples:
|Numbers |Sum|
|1 + 2 + 3|6 |
|4, 5, 6 |15 |
|7; 8; 9 |24 |
|1, 2; 3 |0 |
The executing calling sequence will be changed after using [[mock]] attribute. .
You can find source code of this example from here
Note: Implementation of steps needs Google test/mock