the Compartmented Robust Posix C++ Unit Test system

Chapter 7. 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

[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 void f1(int) = 0;
     };
     
     struct 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"  --------------------------------------------------------------
     
     Unexpected mock function call - returning directly.
         Function call: f1(0x4339c0 pointing to "goodbye)")
     Google Mock tried the following 1 expectation, but it didn't match:
     
     /home/bjorn/devel/crpcut/doc-src/samples/gmock-example.cpp:97: 
       Expected arg #0: is equal to 0x4339c9 pointing to "hello"
                Actual: 0x4339c0 pointing to "goodbye)"
              Expected: to be called once
                Actual: called once - saturated and active
     Unexpected mock function call - returning directly.
         Function call: f1(0x4339c0 pointing to "goodbye)")
     Google Mock tried the following 1 expectation, but it didn't match:
     
     /home/bjorn/devel/crpcut/doc-src/samples/gmock-example.cpp:97: 
       Expected arg #0: is equal to 0x4339c9 pointing to "hello"
                Actual: 0x4339c0 pointing to "goodbye)"
              Expected: to be called once
                Actual: called once - saturated and active
     -------------------------------------------------------------------------------
     ===============================================================================
     FAILED: t3
     phase="destroying"  -----------------------------------------------------------
     /home/bjorn/devel/crpcut/doc-src/samples/gmock-example.cpp:105
     Actual function call count doesn't match this expectation.
              Expected: to be called once
                Actual: never called - unsatisfied and activeActual function call count doesn't match this expectation.
              Expected: to be called once
                Actual: never called - unsatisfied and active
     -------------------------------------------------------------------------------
     ===============================================================================
     Total 3 test cases selected
     UNTESTED : 0
     PASSED   : 1
     FAILED   : 2

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.