tdd - Mocking methods of the object under test -
lately i've been writing objects wherein behavior of 1 method consists of calling 1 of own methods under conditions. test this, i've been mocking methods object calls on makes easier cover each branch in code without combinatorial explosion. considered bad practice. here's example mirrors piece of code i'm working on (written in coffeescript philosophical issue has come me before in other languages too).
class userdatafetcher constructor: (@datasource) -> fetchusernameasync: -> # ... snip ... hits api , raises errors fetchusercommentsasync: -> # ... snip ... hits api , raises errors fetchusernameandusercommentsasync: -> # ... snip ... calls each of above in order , handles errors specially
this pretty straightforward. fetchusernameasync
, fetchusercommentsasync
each interact given @datasource
fetch data. have fetchusernameandusercommentsasync
composed method calling other 2 , handling them in way; in example, might want re-raise errors resulting fetchusernameasync
swallow errors raised fetchusercommentsasync
.
testing behavior of first 2 methods trivial; mock out respective calls @datasource
, assert return data in correct format or allow errors raised. testing behavior of last method have dilemma.
it's still simple method minimal branching logic , delegating of work passing messages. test behavior mocking out "collaborators" , asserting on messages being passed , returning data in appropriate format or failing correctly. difference here has 1 "collaborator", this
. mocking methods of object under test, considered bad practice.
obviously way around move method different object; object 1 method , same mechanics, , allow me mock out collaborator without violating "don't mock methods on object under test" rule. have ridiculous name usernameandcommentsfetcher
, , go having 1 small class 2 tiny, microscopic classes. small classes good, level of granularity might little overkill, , in case exist satisfy "don't mock methods on object under test" rule.
is solid rule or there cases, such this, it's reasonable bend rule?
(note: realize similar question, think example different enough warrant look: as "mockist" tdd practitioner, should mock other methods in same class method under test?)
very few rules in programming 100% solid.
but in case, extract mock setup code fetchusernameasync , fetchusercommentsasync setup methods, , call both of in fetchusernameandusercommentsasync? e.g. (in rspec-like syntax):
specify "fetchusernameasync" setup_username_mock expect(...).to eq ... end specify "fetchcommentsasync" setup_comments_mock expect(...).to eq ... end specify "fetchusernameandcommentsasync" setup_username_mock setup_comments_mock expect(...).to eq ... end
there no need fetchusernameandcommentsasync tests cover paths covered previous specs.
Comments
Post a Comment