I''m trying to use a mock to return a hash so that #each_pair can process it. I can''t get it to work. Whatever I return to #each_pair is ignored and the block never gets executed. Here''s an example illustrating the problem. require File.join(File.dirname(__FILE__), %w[spec_helper]) class MyExample attr_reader :result def example(data) data.each_pair do |key, value| @result = {key => value} end end end describe MyExample, "mock#each_pair fails" do it "should return a hash after processing the mock using each_pair" do sample_mock = mock("sample") real_hash = {:key => :value} sample_mock.should_receive(:each_pair).once.and_return(real_hash) obj = MyExample.new obj.example(sample_mock) obj.result.should == real_hash end end I tried returning different things in case the hash was the wrong intermediate. I tried: #and_return([:key, :value]) #and_return([[:key, :value]]) #and_return(:key, :value) None worked. Is this a bug or am I misusing mocks? cr
What''s the output (or error?) you''re getting? /g On Fri, Mar 28, 2008 at 1:38 PM, Chuck Remes <cremes.devlist at mac.com> wrote:> I''m trying to use a mock to return a hash so that #each_pair can > process it. I can''t get it to work. Whatever I return to #each_pair is > ignored and the block never gets executed. Here''s an example > illustrating the problem. > > require File.join(File.dirname(__FILE__), %w[spec_helper]) > > class MyExample > attr_reader :result > > def example(data) > data.each_pair do |key, value| > @result = {key => value} > end > end > end > > describe MyExample, "mock#each_pair fails" do > it "should return a hash after processing the mock using each_pair" > do > sample_mock = mock("sample") > real_hash = {:key => :value} > sample_mock.should_receive(:each_pair).once.and_return(real_hash) > obj = MyExample.new > obj.example(sample_mock) > obj.result.should == real_hash > end > end > > I tried returning different things in case the hash was the wrong > intermediate. I tried: > #and_return([:key, :value]) > #and_return([[:key, :value]]) > #and_return(:key, :value) > > None worked. Is this a bug or am I misusing mocks? > > cr > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >-- George Anderson BenevolentCode LLC O: (410) 461-7553 C: (410) 218-5185 george at benevolentcode.com
It ends up comparing nil to real_hash. This happens because the #result accessor never gets initialized due to the block never getting executed. cr On Mar 28, 2008, at 12:47 PM, George Anderson wrote:> What''s the output (or error?) you''re getting? > > /g > > On Fri, Mar 28, 2008 at 1:38 PM, Chuck Remes > <cremes.devlist at mac.com> wrote: >> I''m trying to use a mock to return a hash so that #each_pair can >> process it. I can''t get it to work. Whatever I return to #each_pair >> is >> ignored and the block never gets executed. Here''s an example >> illustrating the problem. >> >> require File.join(File.dirname(__FILE__), %w[spec_helper]) >> >> class MyExample >> attr_reader :result >> >> def example(data) >> data.each_pair do |key, value| >> @result = {key => value} >> end >> end >> end >> >> describe MyExample, "mock#each_pair fails" do >> it "should return a hash after processing the mock using each_pair" >> do >> sample_mock = mock("sample") >> real_hash = {:key => :value} >> sample_mock.should_receive(:each_pair).once.and_return(real_hash) >> obj = MyExample.new >> obj.example(sample_mock) >> obj.result.should == real_hash >> end >> end >> >> I tried returning different things in case the hash was the wrong >> intermediate. I tried: >> #and_return([:key, :value]) >> #and_return([[:key, :value]]) >> #and_return(:key, :value) >> >> None worked. Is this a bug or am I misusing mocks? >> >> cr >> _______________________________________________ >> rspec-users mailing list >> rspec-users at rubyforge.org >> http://rubyforge.org/mailman/listinfo/rspec-users >> > > > > -- > > George Anderson > > BenevolentCode LLC > O: (410) 461-7553 > C: (410) 218-5185 > > george at benevolentcode.com > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users
On Fri, Mar 28, 2008 at 1:38 PM, Chuck Remes <cremes.devlist at mac.com> wrote:> I''m trying to use a mock to return a hash so that #each_pair can > process it. I can''t get it to work. Whatever I return to #each_pair is > ignored and the block never gets executed. Here''s an example > illustrating the problem. > > require File.join(File.dirname(__FILE__), %w[spec_helper]) > > class MyExample > attr_reader :result > > def example(data) > data.each_pair do |key, value| > @result = {key => value} > end > end > end > > describe MyExample, "mock#each_pair fails" do > it "should return a hash after processing the mock using each_pair" > do > sample_mock = mock("sample") > real_hash = {:key => :value} > sample_mock.should_receive(:each_pair).once.and_return(real_hash) > obj = MyExample.new > obj.example(sample_mock) > obj.result.should == real_hash > end > endeach_pair does not return the hash, it yields it to a block. Try this: sample_mock.should_receive(:each_pair).once.and_yield(real_hash)> > I tried returning different things in case the hash was the wrong > intermediate. I tried: > #and_return([:key, :value]) > #and_return([[:key, :value]]) > #and_return(:key, :value) > > None worked. Is this a bug or am I misusing mocks? > > cr > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
On Mar 28, 2008, at 1:46 PM, David Chelimsky wrote:> On Fri, Mar 28, 2008 at 1:38 PM, Chuck Remes > <cremes.devlist at mac.com> wrote: >> I''m trying to use a mock to return a hash so that #each_pair can >> process it. I can''t get it to work. Whatever I return to #each_pair >> is >> ignored and the block never gets executed. Here''s an example >> illustrating the problem. >> >> require File.join(File.dirname(__FILE__), %w[spec_helper]) >> >> class MyExample >> attr_reader :result >> >> def example(data) >> data.each_pair do |key, value| >> @result = {key => value} >> end >> end >> end >> >> describe MyExample, "mock#each_pair fails" do >> it "should return a hash after processing the mock using each_pair" >> do >> sample_mock = mock("sample") >> real_hash = {:key => :value} >> sample_mock.should_receive(:each_pair).once.and_return(real_hash) >> obj = MyExample.new >> obj.example(sample_mock) >> obj.result.should == real_hash >> end >> end > > each_pair does not return the hash, it yields it to a block. Try this: > > sample_mock.should_receive(:each_pair).once.and_yield(real_hash)Dave, thanks for the hint. That almost worked but I got this error: Spec::Mocks::MockExpectationError in ''MyExample mock#each_pair fails should return a hash after processing the mock using each_pair'' Mock ''sample'' yielded |{:key=>:value}| to block with arity of 2 Changing it slightly allowed it to work correctly: describe MyExample, "mock#each_pair fails" do it "should return a hash after processing the mock using each_pair" do sample_mock = mock("sample") real_hash = {:key => :value} sample_mock .should_receive(:each_pair).once.and_yield(real_hash.keys.first, real_hash.values.first) obj = MyExample.new obj.example(sample_mock) obj.result.should == real_hash end end Thanks for your help. SrBaker has been enriched as a result. :-) cr