Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Given/When/Then pattern with mocks (Google Mock)?

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?

like image 311
Netrix Avatar asked Aug 19 '13 07:08

Netrix


People also ask

How do you make a mock gMock?

Using the Turtle interface as example, here are the simple steps you need to follow: Derive a class MockTurtle from Turtle . Take a virtual function of Turtle (while it's possible to mock non-virtual methods using templates, it's much more involved). In the public: section of the child class, write MOCK_METHOD();

Why or when is it useful to test using mocks?

Only use a mock (or test double) “when testing things that cross the dependency inversion boundaries of the system” (per Bob Martin). If I truly need a test double, I go to the highest level in the class hierarchy diagram above that will get the job done. In other words, don't use a mock if a spy will do.

What is gMock and Gtest?

Google Test is a popular C++ unit testing framework developed by Google that can be used together with the closely related mocking extension framework, Google Mock, to test code that conforms to the SOLID principles for object-oriented software design.

What is Expect_call Gtest?

EXPECT_CALL not only defines the behavior, but also sets an expectation that the method will be called with the given arguments, for the given number of times (and in the given order when you specify the order too).


1 Answers

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);
}
like image 105
RA. Avatar answered Oct 04 '22 20:10

RA.