the Compartmented Robust Posix C++ Unit Test system

Chapter 8. Using google mock

Using google-mock with crpcut is straight forward. The only important thing to keep in mind is to always #include <gmock/gmock.h> before #include <crpcut.hpp>, and to link your test program with -lgmock, -lgtest and, of course also -lcrpcut or -lcrpcut_basic. Depending on your version of google-mock you may also need -lpthread.

[Tip]Tip
Experience has shown that it's beneficial to use fixtures to set up common mock sequences. See Fixtures for common test setups for information on writing fixtures.

A simple example using mock objects:

     
     #include <gmock/gmock.h>
     #include <crpcut.hpp>
     
     
     struct iface1 {
       virtual ~iface1() {}
       virtual void f1(int) = 0;
     };
     
     struct iface2 {
       virtual ~iface2() {}
       virtual void f1(const char *) = 0;
     };
     
     struct mock1 : iface1 {
       MOCK_METHOD1(f1, void(int));
     };
     
     struct mock2 : iface2 {
       MOCK_METHOD1(f1, void(const char*));
     };
     
     struct fix_base {
       mock1 m1;
       mock2 m2;
     };
     
     class fix_seq1 : public fix_base {
     public:
       fix_seq1() {
         EXPECT_CALL(m1, f1(3)).InSequence(s);
         EXPECT_CALL(m2, f1("hello")).InSequence(s);
       }
     private:
       testing::Sequence s; // prevent test cases from changing the sequence
     };
     
     class fix_seq2 : public fix_base {
     public:
       fix_seq2() {
         EXPECT_CALL(m1, f1(3)).InSequence(s1, s2);
         EXPECT_CALL(m1, f1(4)).InSequence(s1);
       }
     protected:
       testing::Sequence s1; // open-ended, for test-cases
       testing::Sequence s2; // to add more to the sequences
     };
     
     
     template <int N>
     class to_test
     {
     public:
       to_test(iface1 &o1) : obj(0) { o1.f1(N); }
       ~to_test() { if (obj) { obj->f1("goodbye)"); } }
       void greet(iface2 &o) { obj = &o; o.f1("hello"); }
       void no_goodbye() { obj = 0; }
     private:
       iface2 *obj;
       };
     
     TEST(simple_3_hello, fix_seq1)
     {
       to_test<3> object(m1);
       object.greet(m2);
       object.no_goodbye();
     }
     
     TEST(t2, fix_seq2)
     {
       // add more to the started sequence
       EXPECT_CALL(m2, f1("hello")).InSequence(s2);
       to_test<3> object(m1);
       object.greet(m2);
     }
     
     TEST(t3, fix_seq2)
     {
       // add other things to the started sequence
       EXPECT_CALL(m2, f1("goodbye")).InSequence(s2);
       to_test<3> object(m1);
     }
     
     
     int main(int argc, char *argv[])
     {
       return crpcut::run(argc, argv);
     }

The result from running the test program is:


     FAILED!: t2
     phase="running"  --------------------------------------------------------------
     samples/gmock-example.cpp:96
     
     Unexpected mock function call - returning directly.
         Function call: f1(0x432e5f pointing to "goodbye)")
     Google Mock tried the following 1 expectation, but it didn't match:
     
     samples/gmock-example.cpp:99: EXPECT_CALL(m2, f1("hello"))...
       Expected arg #0: is equal to 0x432c93 pointing to "hello"
                Actual: 0x432e5f pointing to "goodbye)"
              Expected: to be called once
                Actual: called once - saturated and active
     Unexpected mock function call - returning directly.
         Function call: f1(0x432e5f pointing to "goodbye)")
     Google Mock tried the following 1 expectation, but it didn't match:
     
     samples/gmock-example.cpp:99: EXPECT_CALL(m2, f1("hello"))...
       Expected arg #0: is equal to 0x432c93 pointing to "hello"
                Actual: 0x432e5f pointing to "goodbye)"
              Expected: to be called once
                Actual: called once - saturated and active
     -------------------------------------------------------------------------------
     ===============================================================================
     FAILED!: t3
     phase="destroying"  -----------------------------------------------------------
     samples/gmock-example.cpp:107
     Actual function call count doesn't match EXPECT_CALL(m2, f1("goodbye"))...
              Expected: to be called once
                Actual: never called - unsatisfied and activeActual function call count doesn't match EXPECT_CALL(m2, f1("goodbye"))...
              Expected: to be called once
                Actual: never called - unsatisfied and active
     -------------------------------------------------------------------------------
     ===============================================================================
     3 test cases selected
     
                    Sum   Critical   Non-critical
     PASSED   :       1          1              0
     FAILED   :       2          2              0

As expected, google-mock finds and reports errors, both directly when being called with the wrong values, and during fixture destruction time if required calls haven't been made. Please refer to the documentation on http://code.google.com/p/googlemock for information about how to use google-mock.