How to use Given/When/Then pattern with mocks (Google Mock)?
c++, googlemock, googletest, unit-testing
Solution
The `EXPECT_CALL` macro can be thought of as a way of testing interaction between a class and another class. As such, if you are using it with another `EXPECT` macro, then your test is likely testing two things, which is why it appears to conflict with the "Given-When-Then" paradigm (also known as "Arrange-Act-Assert").
If you just need to set up some behavior on your mock object for testing, use the `ON_CALL` macro instead:
TEST(TestFixture, TestName)
{
// Given
int a = 5;
int b = 6;
int expectedResult = 30;
MightCalculatorMock mock;
ON_CALL(mock, multiply(a,b))
.WillByDefault(Return(expectedResult));
// When
int result = Multiply(mock, a, b);
// Then
EXPECT_EQ(expectedResult, result);
}
If you are actually looking to test the iteraction between your system under test and some other collaborator, you can use an "Arrange-Expect-Act" pattern:
TEST(TestFixture, CalculatorIsCalledProperly)
{
// Arrange
int a = 5;
int b = 6;
int expectedResult = 30;
MightCalculatorMock mock;
// Expect
EXPECT_CALL(mock, multiply(Eq(a),Eq(b)));
// Act
int result = Multiply(mock, a, b);
}
Problem
I'm using the Given/When/Then pattern to make test code much clearer. Since I'm writing those tests in C++ I chosed to use Google Test. With tests the pattern is clear, because I do sth like this: ``` TEST(TestFixture, TestName) { // Given int a = 5; int b = 6; int expectedResult = 30; // When int result = Multiply(a, b); // Then EXPECT_EQ(expectedResult, result); } ``` But with mocks it stops being clear since there appear some EXPECTs in the Given part. The Given part suppose to be a setup step. Please see an example: ``` TEST(TestFixture, TestName) { // Given int a = 5; int b = 6; int expectedResult = 30; MightCalculatorMock mock; EXPECT_CALL(mock, multiply(a,b)) .WillOnce(Return(expectedResult)); // When int result = Multiply(mock, a, b); // Then EXPECT_EQ(expectedResult, result); } ``` Is this approach correct? How the Given/When/Then comments should be placed in the test code, where?