Question

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?

Was it helpful?

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);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top