Ashley Moran
2008-May-18 09:13 UTC
[rspec-users] Using Hash to mock classes that respond to :[]
Hi I''ve been doing this a while now. If I have a class that responds to : [], and all I''m interested in stubbing is that method, then instead of using a mock I just create a hash. (Similarly, you could create an array when you are testing an Enumerable object.) Example from code I just worked on, where uses MigrationGraph#[] looks up graph vertices by name: @migration_graph = { # "name" => vertex "changeset 1 migration 1" => @migration_a, "changeset 1 migration 2" => @migration_b, "changeset 2 migration 1" => @migration_c, "changeset 2 migration 2" => @migration_d } What I''m really interested in is what happens to (some of) the four migrations, not the migration graph itself. I just wondered if anyone else did this. Generally doing unusual things is a sign something is amiss. Ashley -- http://www.patchspace.co.uk/ http://aviewfromafar.net/
John D. Hume
2008-May-19 16:57 UTC
[rspec-users] Using Hash to mock classes that respond to :[]
I do that sort of thing pretty often. I would just point out that you should avoid calling that mocking, since there are no expectations in place and therefore no verification of the specific way the code being specified interacts with the MigrationGraph. According to the definitions in http://martinfowler.com/articles/mocksArentStubs.html (which are apparently from http://xunitpatterns.com/ but I haven''t read it), your hash is a ''fake'' MigrationGraph. -hume. On Sun, May 18, 2008 at 5:13 AM, Ashley Moran <ashley.moran at patchspace.co.uk> wrote:> Hi > > I''ve been doing this a while now. If I have a class that responds to :[], > and all I''m interested in stubbing is that method, then instead of using a > mock I just create a hash. (Similarly, you could create an array when you > are testing an Enumerable object.) > > Example from code I just worked on, where uses MigrationGraph#[] looks up > graph vertices by name: > > @migration_graph = { > # "name" => vertex > "changeset 1 migration 1" => @migration_a, > "changeset 1 migration 2" => @migration_b, > "changeset 2 migration 1" => @migration_c, > "changeset 2 migration 2" => @migration_d > } > > What I''m really interested in is what happens to (some of) the four > migrations, not the migration graph itself. > > I just wondered if anyone else did this. Generally doing unusual things is > a sign something is amiss. > > Ashley > > > -- > http://www.patchspace.co.uk/ > http://aviewfromafar.net/ > > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20080519/9022d4ff/attachment.html>
Ashley Moran
2008-May-19 21:01 UTC
[rspec-users] Using Hash to mock classes that respond to :[]
On 19 May 2008, at 17:57, John D. Hume wrote:> I do that sort of thing pretty often. > > I would just point out that you should avoid calling that mocking, > since there are no expectations in place and therefore no > verification of the specific way the code being specified interacts > with the MigrationGraph. According to the definitions in http://martinfowler.com/articles/mocksArentStubs.html(which > are apparently from http://xunitpatterns.com/ but I haven''t read > it), your hash is a ''fake'' MigrationGraph.I hope you will forgive my sloppy use of TDD terms :) Actually I''ve never liked the use of the word "mock" to mean "verified stub" or something similar, as "mock" and "fake" are synonyms in everyday English. Maybe that''s because in RSpec you can create expectations on any object (blank mocks or arbitrary other objects). After all consider these two snippets (which is condensed from how you would write real code): @store = mock("store") @store.stub!(:[]).and_return(1, 2) # implies you know the order of calls @store.should_receive(:[]).with("a").and_return(1) @store.should_receive(:[]).with("b").and_return(2) @store = { "a" => 1, "b" => 2 } @store.should_receive(:[]).with("a").and_return(1) @store.should_receive(:[]).with("b").and_return(2) Only one is a mock by definition, but most sane code (and specs) would behave the same with either. Surely since they both quack, they are both ducks? As for the terms in the Fowler article, this is how I feel: * Dummy - I''m ok with this, I use symbols as dummies all the time * Fake - an "in-memory database" isn''t fake, it''s just an implementation that satisfies the needs of the code at hand (ie the spec). You could say a single-server database is fake, if a load- balanced cluster is needed to satisfy availability requirements. * Stubs - I think of a stub as a message-level concept, not an object- level one. To me, an object with stubs could be called a "fake" since it could never be used for a real purpose, no matter how simple the real task. * Mocks - in RSpec these are just objects that complain if sent an unexpected message. They become fake (my sense of the word) objects when you stub responses on them, although I prefer to call them mocks. Alternative words that might make more sense in a duck-typed language are "substitute" instead of "fake" (that''s what the use of a Hash about would be) and "mock" instead of "stub". I don''t know what you''d call a Fowler mock in that case - maybe the idea doesn''t make sense when any object can have expectations. I also don''t know what you''d call a partial mock - an aberration, perhaps? :) I''m sure this is all nit-picking, but it''s taken me two years to learn the "official" words and they still feel unnatural (which is why I always fall back to my own version). End rant! Ashley PS I think my use of a substitute Hash above is actually a symptom of violation Tell Don''t Ask, I should probably pass the names of the migrations to the MigrationGraph and have *it* unapply them all. That would also clean up some other really hideous code in the Apply class where #run goes poking around deleting stuff inside the graph (it''s a did-I-really-write that moment). I wish I had the foresight to do things right in the first place! -- http://www.patchspace.co.uk/ http://aviewfromafar.net/