vmcpherson / googlemock

Automatically exported from code.google.com/p/googlemock
BSD 3-Clause "New" or "Revised" License
0 stars 0 forks source link

record the behavior of real objects and play it back as EXPECT_CALLs #71

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
When replacing an expensive/slow/brittle dependency with a mock, the user
first needs to know which methods are called with what arguments, and what
values are returned.  It would be nice for gmock to allow a "mock recorder"
observe the behavior of a real mock, and then print out EXPECT_CALL()
sequences to match what happened.  The user can then copy-n-paste the
printed expectations into a mock-based test.

Bonus point for allowing switching between mock and real objects via a
command line flag.

Original issue reported on code.google.com by zhanyong...@gmail.com on 15 Sep 2009 at 11:16

GoogleCodeExporter commented 9 years ago

Original comment by w...@google.com on 26 Feb 2010 at 7:15

GoogleCodeExporter commented 9 years ago
Some design ideas:

Given a FooInterface and a concrete implementation Foo, a user can write:

// "Mockable" means the class can be used as either a mock or the real thing.
class MockableFoo : public FooInterface {
 public:
  DELEGATE_TO(Foo);

  MOCKABLE_METHOD2(Bar, int(bool x, char y));
  MOCKABLE_METHOD1(Baz, void(int n));
  ...
};

TEST(...) {
  scoped_ptr<Foo> foo;
  MockableFoo mf;
  if (use_real_foo) {
    foo.reset(new Foo);
    mf.SetMockName("mf");
    mf.DelegateMockCallsTo(*foo);
  } else {
    // Set expectations.  To be filled.
  }

  // Exercises code that uses mf.
  DoSomething(&mf);
  // The above statement calls:
    mf.Bar(true, 'a');  // Calls foo.Bar() and logs the call args & result.
    mf.Baz(5);  // Calls foo.Baz() and logs the call args & result.
    ...

  testing::Mock::DumpCallLog();
}

Run the test with use_real_foo being true, DumpCallLog() will print
something like:

  InSequence s;
  EXPECT_CALL(mf, Bar(true, 'a')).WillOnce(Return(42));
  EXPECT_CALL(mf, Baz(5));
  ...

which the user can copy-n-paste into the "set expectations" branch in
the test, with some (hopefully minor) editing.

Then the user can run the test as a unit test with use_real_foo being
false.  No real Foo object will be used.  From time to time, he may
run the test as an integartion test, using the real Foo object,

Original comment by w...@google.com on 8 Apr 2010 at 6:15

GoogleCodeExporter commented 9 years ago
It's quite complex to implement.  May not be worth it.

Original comment by w...@google.com on 5 Jun 2010 at 6:45

GoogleCodeExporter commented 9 years ago
I decided to change to priority back to medium.  While it requires a lot of 
work, it can be very rewarding.  We still might want to do it when we get more 
resources.

Original comment by w...@google.com on 27 Sep 2010 at 9:31