On 17/01/2012 16:18, Chris Cleeland wrote:
(...)
What I found in my situation, though, was that mocking took a substantial amount of development effort in a "legacy"(*) body of code such that creating tests that rely upon mocking was more trouble than it was worth at first evaluation, i.e., it did not save me more time than it cost. As this was my first experience with an actual mocking framework (as opposed to ad-hoc bespoke stuff created for a single purpose), I'm not sure if it's a framework issue, a user (me) issue, an impedance mismatch between the framework and legacy code, or what. I suspect that the reality is that it's a little of all of them.
If anybody knows a mocking framework that slides easily into existing, and sometimes grungy (from a TDD perspective), code base, I'd love to hear about it.
(*) By "legacy" I mean code that was not written with a test-driven development mindset.
Hi Chris, I don't have the answer to your question but if your legacy code was developed with "traditional" unit tests, or even without tests, it isn't going to be easy to introduce mock objects because it actually means turning everything upside-down. Using mock objects tends to drive the code to be more "push" (ask others to do things) and less "pull" (collect data in order to do things) than the usual. Most of the test cases don't even check any results in the end, they just expect calls. It's not just a convenient way of faking components in order to test them more easily, it's also a way of driving the code a bit differently. From my experience, trying to use mock objects after a component has been written results in lengthy test cases which need to configure many mock objects and/or many expectations in order to work. I have seen for instance tests like this : BOOST_AUTO_TEST_CASE( some_test ) { some_mock a; MOCK_EXPECT( a.get_some_data ).once().with( -100.f, 100.f ).returns( 0 ); MOCK_EXPECT( a.get_some_data ).once().with( 0.f, 100.f ).returns( 1 ); MOCK_EXPECT( a.get_some_data ).once().with( 100.f, 100.f ).returns( -1 ); // etc... for A LOT of lines some_class b( a ); b.do_something( 12, 42, 77 ); BOOST_CHECK_EQUAL( 654, b.result() ); } This is indeed cumbersome to write and hard to maintain, and to someone accustomed to TDD it's a smell this most likely wasn't. :) My usual approach is either scrap the component and start from scratch, or just leave it be if it doesn't impact much the rest of the system... Mathieu