top | item 3700276

(no title)

tdavis | 14 years ago

Now make some other code use your "mock" without editing its source. Now assert on the calls made to "bar()," including arguments. Now make it raise an exception without writing a second class. And make it return something else without writing a third. Now patch a built-in. And a context manager. And a dictionary. When you're done with that, mock a class without writing a new class at all.

If you honestly think that sub-classing is equivalent to mocking/stubbing, you don't understand the purpose of the activity.

discuss

order

jrockway|14 years ago

I know libraries can do all those things, but I've never preferred it over the real thing. As an example, I might do something like this (not Python):

   my $bar = 0;
   class FakeFoo {
      sub bar { return $bar }
   }

   my $thing = ThingToTest->new( foo => FakeFoo->new );
   $foo = 42;
   is $thing->make_bar_two_bigger, 44;
   $foo = -10;
   is $thing->make_bar_two_bigger, -12;
Mock enthusiasts would write:

   my $fake_foo = Mock->new( Foo->class )->instance;
   $fake_foo->return_sequence( bar => [42, -10] );
   my $thing = ThingToTest->new( foo => $fake_foo );
   is $fake_foo->make_bar_two_bigger, 44;
   is $fake_foo->make_bar_two_bigger, -12;
   ok $fake_foo->ensure_exhausted('bar');
Yes, it's less lines, but I think it's harder to read because the values are being set up long before they're used.

jrockway|14 years ago

Well, this was typo-y. $foo in the first codeblock should be $bar, and $fake_foo->make_bar_two_bigger should be $thing->make_bar_two_bigger. More coffee is required :)