Is it possible to create a stub that returns hash values. For example I would like to convert this: @siteItem = stub(''plmSiteItem'', :one => "uno") To something like this: @siteItem = stub(''plmSiteItem'', {''one'' => ''uno'', ''two'' => ''dos''} ) So that I can do this: @siteItem[''one''] should == ''uno'' @siteItem[''two''] should == ''dos'' Actually I first tried to use method double instead of stub - even though I still don''t know when each is preferred - but double raised a missing method error for some reason.
On 20 Oct 2009, at 17:36, Carl Graff wrote:> Is it possible to create a stub that returns hash values. > > For example I would like to convert this: > @siteItem = stub(''plmSiteItem'', :one => "uno") > > To something like this: > @siteItem = stub(''plmSiteItem'', {''one'' => ''uno'', ''two'' => ''dos''} ) > > So that I can do this: > @siteItem[''one''] should == ''uno'' > @siteItem[''two''] should == ''dos''Hi Carl In Ruby, code like my_object["foo"] is implemented with the method [] eg: class Thing def [](key) # ... end end So in RSpec you have to stub :[] like this: describe "stub hash" do it "quacks like a hash" do stub_hash = stub("hash") stub_hash.stub(:[]).with("one").and_return("uno") stub_hash.stub(:[]).with("two").and_return("dos") stub_hash["one"].should == "uno" stub_hash["two"].should == "dos" end end> Actually I first tried to use method double instead of stub - even > though I still don''t know when each is preferred - but double raised > a missing method error for some reason.Can you post your code? HTH Ashley -- http://www.patchspace.co.uk/ http://www.linkedin.com/in/ashleymoran http://aviewfromafar.net/
Ashley Moran wrote:> > On 20 Oct 2009, at 17:36, Carl Graff wrote: > >> Is it possible to create a stub that returns hash values. >> >> For example I would like to convert this: >> @siteItem = stub(''plmSiteItem'', :one => "uno") >> >> To something like this: >> @siteItem = stub(''plmSiteItem'', {''one'' => ''uno'', ''two'' => ''dos''} ) >> >> So that I can do this: >> @siteItem[''one''] should == ''uno'' >> @siteItem[''two''] should == ''dos'' > > Hi Carl > > In Ruby, code like my_object["foo"] is implemented with the method [] eg: > > class Thing > def [](key) > # ... > end > end > > So in RSpec you have to stub :[] like this: > > describe "stub hash" do > it "quacks like a hash" do > stub_hash = stub("hash") > stub_hash.stub(:[]).with("one").and_return("uno") > stub_hash.stub(:[]).with("two").and_return("dos") > stub_hash["one"].should == "uno" > stub_hash["two"].should == "dos" > end > end > > >> Actually I first tried to use method double instead of stub - even >> though I still don''t know when each is preferred - but double raised >> a missing method error for some reason. > > > Can you post your code? > > > HTH > > Ashley > >Thanks Ashley that works perfect :-)
wait why do you want to do this?? Just use a regular hash and do state-based assertions on it. Or determine the role that this hash-like thing is doing, and use a mock to define a proper interface. Ashley''s solution works but I am very skeptical that the approach is a good one. Can you post some code? Pat On Tue, Oct 20, 2009 at 9:36 AM, Carl Graff <carl.graff at cox.net> wrote:> Is it possible to create a stub that returns hash values. > > For example I would like to convert this: > ?@siteItem = stub(''plmSiteItem'', :one => "uno") > > To something like this: > ?@siteItem = stub(''plmSiteItem'', {''one'' => ''uno'', ''two'' => ''dos''} ) > > So that I can do this: > ? @siteItem[''one''] should == ''uno'' > ? @siteItem[''two''] should == ''dos'' > > > Actually I first tried to use method double instead of stub - even though I > still don''t know when each is preferred - but double raised a missing method > error for some reason. > > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
On 21 Oct 2009, at 08:41, Pat Maddox wrote:> wait why do you want to do this?? Just use a regular hash and do > state-based assertions on it. Or determine the role that this > hash-like thing is doing, and use a mock to define a proper interface. > Ashley''s solution works but I am very skeptical that the approach is > a good one. Can you post some code?I had wondered the same thing myself... but I figured if my suspicions were right, a fallout problem would be posted soon enough :) Ashley -- http://www.patchspace.co.uk/ http://www.linkedin.com/in/ashleymoran http://aviewfromafar.net/
Well i just started using RSpec about a week ago and mostly I was just trying to learn how to use mocks as I could have easily just created the real object in this case. Anyway, I had a real object, that needed to contain a hash of a yet to be created object, which itself contained a hash of attributes. Here is the code that I used to get the tests to past - but it simulated a method called "name" in the mock that returned a string value instead of a hash of string values I desired. ################## describe ErpItemMasterRec do context "initializing" do before(:each) do @itemNo = ''004-907019-004'' @plmItm = ErpItemMasterRec.new(@itemNo) [''GT'',''CH'',''NB''].each do |site| plmSiteItem = stub(''plmSiteItem'', :name => "#{site}-site") @plmItm.sites[site] = plmSiteItem end end it "should create new instance when receiving a valid item number as a string" do @itemNo.should be_instance_of(String) @plmItm.should be_instance_of(ErpItemMasterRec) end it "should store item data from each mfg site that contains the valid item number" do @plmItm.sites[''GT''].name.should == ''GT-site'' @plmItm.sites[''CH''].name.should == ''CH-site'' @plmItm.sites[''NB''].name.should == ''NB-site'' end end ################## I wanted the last part to be more like: it "should store item data from each mfg site that contains the valid item number" do @plmItm.sites[''GT''].attr[''NAME''].should == ''GT-site'' @plmItm.sites[''CH''].attr[''NAME''].should == ''CH-site'' @plmItm.sites[''NB''].attr[''NAME''].should == ''NB-site'' end In truth, due to my inexperience and confusion, mocks seem to slow my development more than just creating real objects. But since there has been so much effort to put these into testing frameworks, I think it must be important to try and learn when it is appropriate to use them. Thanks, Carl Ashley Moran wrote:> > On 21 Oct 2009, at 08:41, Pat Maddox wrote: > >> wait why do you want to do this?? Just use a regular hash and do >> state-based assertions on it. Or determine the role that this >> hash-like thing is doing, and use a mock to define a proper interface. >> Ashley''s solution works but I am very skeptical that the approach is >> a good one. Can you post some code? > > I had wondered the same thing myself... but I figured if my suspicions > were right, a fallout problem would be posted soon enough :) > > Ashley >
Hi Carl, Some thoughts below... On 21 Oct 2009, at 18:12, Carl Graff wrote:> Well i just started using RSpec about a week ago and mostly I was > just trying to learn how to use mocks as I could have easily just > created the real object in this case. > > Anyway, I had a real object, that needed to contain a hash of a yet > to be created object, which itself contained a hash of attributes. > > Here is the code that I used to get the tests to past - but it > simulated a method called "name" in the mock that returned a string > value instead of a hash of string values I desired. > > ################## > describe ErpItemMasterRec do > context "initializing" do > before(:each) do > @itemNo = ''004-907019-004'' > @plmItm = ErpItemMasterRec.new(@itemNo) > [''GT'',''CH'',''NB''].each do |site| > plmSiteItem = stub(''plmSiteItem'', :name => "#{site}-site") > @plmItm.sites[site] = plmSiteItem > end > end > > it "should create new instance when receiving a valid item number as > a string" do > @itemNo.should be_instance_of(String) > @plmItm.should be_instance_of(ErpItemMasterRec) > end > > it "should store item data from each mfg site that contains the > valid item number" do > @plmItm.sites[''GT''].name.should == ''GT-site'' > @plmItm.sites[''CH''].name.should == ''CH-site'' > @plmItm.sites[''NB''].name.should == ''NB-site'' > end > end > ################## > > I wanted the last part to be more like: > > it "should store item data from each mfg site that contains the > valid item number" do > @plmItm.sites[''GT''].attr[''NAME''].should == ''GT-site'' > @plmItm.sites[''CH''].attr[''NAME''].should == ''CH-site'' > @plmItm.sites[''NB''].attr[''NAME''].should == ''NB-site'' > end > > > In truth, due to my inexperience and confusion, mocks seem to slow > my development more than just creating real objects. But since there > has been so much effort to put these into testing frameworks, I > think it must be important to try and learn when it is appropriate > to use them.The real point of mock objects (which most people miss) is to give you a lightweight way to sketch out the behaviour of another object that the object you''re currently building will collaborate with - without having to commit to actually building the collaborator yet. This allows you to play out design ideas about the relationship between the two objects and get them right before you sit down and write the implementation of the collaborator. In this case, it seems you''ve actually got very little behaviour in the class you''re apparently testing (the ErpItemMasterRec class) - it''s pretty much just a container for this list of sites, which are all being set up in the before block. Where will this list of sites come from when the code runs in production? Would it make more sense to pass that in to the ErpItemMasterRec constructor? If you really want to get your head around this stuff, I highly recommend http://www.mockobjects.com/book/ (though the examples are in Java)> > Thanks, > Carl > > > Ashley Moran wrote: >> >> On 21 Oct 2009, at 08:41, Pat Maddox wrote: >> >>> wait why do you want to do this?? Just use a regular hash and do >>> state-based assertions on it. Or determine the role that this >>> hash-like thing is doing, and use a mock to define a proper >>> interface. >>> Ashley''s solution works but I am very skeptical that the approach is >>> a good one. Can you post some code? >> >> I had wondered the same thing myself... but I figured if my >> suspicions were right, a fallout problem would be posted soon >> enough :) >> >> Ashley >> > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-userscheers, Matt http://mattwynne.net +447974 430184
On Wed, Oct 21, 2009 at 1:12 PM, Carl Graff <cagraff at cox.net> wrote:> > In truth, due to my inexperience and confusion, mocks seem to slow my > development more than just creating real objects. But since there has been > so much effort to put these into testing frameworks, I think it must be > important to try and learn when it is appropriate to use them.That is a fallacious line of reasoning. A lot of effort has also gone into American football, every Michael Bay movie, and Windows Vista. QED. My suggestion on _any_ technology is not to use it in serious practice unless you have a good idea _why_ you''re using it and what it can offer you. "I want to play with this and determine what the fuss is" can be a good reason -- provided you have the leisure to do so -- but "All the hotshot programmers say it''s important" is not sufficient and _durable_ reason in itself. If you don''t know _why_ they say it, find out. If you''re not sure you grok it, try it both ways, but be objective about the results. Don''t hold onto a practice blindly. If your testing so far seems to be going just fine without mocks and you haven''t hit any snags, great. Maybe you''re not hitting use cases where they''re really helpful. Maybe you''ve figured out how to address the same problems in other ways. Heck, maybe everyone else is _wrong_ about them. (This does in fact happen in software culture, though it''s easy to overestimate the likelihood.) Do what works, as long as it works. When it *stops* working for you, or you advance enough in your own proficiency that things you hadn''t thought about before start to seem questionable or annoying, be prepared to adapt and to try things. Maybe at that point, mocks will be just what you need. -- Have Fun, Steve Eley (sfeley at gmail.com) ESCAPE POD - The Science Fiction Podcast Magazine http://www.escapepod.org
On 21 Oct 2009, at 19:18, Stephen Eley wrote:> On Wed, Oct 21, 2009 at 1:12 PM, Carl Graff <cagraff at cox.net> wrote: >> >> In truth, due to my inexperience and confusion, mocks seem to slow my >> development more than just creating real objects. But since there >> has been >> so much effort to put these into testing frameworks, I think it >> must be >> important to try and learn when it is appropriate to use them. > > That is a fallacious line of reasoning. A lot of effort has also gone > into American football, every Michael Bay movie, and Windows Vista. > QED.To be fair, Carl did say he wanted to "learn when it is appropriate to use them" as opposed to just using them indiscriminately. And the answer may be "never". I suppose it''s quite possible that mocks do suck, and we just haven''t realised yet. But that''s ok, they suck less than inspecting instance variables, so I''m happy, at least. What I would suggest is to not try to learn how to use mocks on production code*, unless you have pretty thorough means of integration testing. Incorrect mocking leads to brittle specs* and that leads to hidden bugs* and thrashing during refactoring*. In fact, if you don''t use a tool such as Cucumber, I''d recommend learning that over mocking first. (You don''t need to use Cucumber, but it''s more suited for high-level descriptions than RSpec.) As RSpec lets you refactor without risk of breaking units of code, Cucumber lets you refactor your code and specs across units. That gives you a metric on how well you''re using mocks - unexpected Cucumber failures indicate a faulty assumption somewhere. Of course, that assumes your Cucumber features are solid... Just my coin of small denomination. Other learning strategies are available. Ashley * which was my situation -- http://www.patchspace.co.uk/ http://www.linkedin.com/in/ashleymoran http://aviewfromafar.net/