[rspec-users] stubbing a method that yeilds sequential results

David Chelimsky dchelimsky at gmail.com
Sun Aug 12 09:38:36 EDT 2007


On 8/12/07, rupert <rupert_apsc at rupespad.com> wrote:
> I've just found myself stuck trying to rspec something so am hoping
> someone more knowledgable can help.
>
> I have a Connector class which has a class method 'results' that
> yields results it get from a network service based on a set of
> attributes that I pass to it.  I am wanting to yield these results
> from my Intermediate class up to the next 'level' so the basic no
> frills set up would be this:
>
> class Intermediate
>    def self.results(attributes)
>      Connector.each_result(attributes) do |result|
>        yield result
>      end
>    end
> end
>
> I've worked out how to stub things for the case where the Connector.
> each_result method yields a result once
>
> #setup
> @result = mock("result")
> Connector.stub!(:each_result).and_yield(@result)
>
> @attributes = {}
> @results = []
> @block = Proc.new { |r| @results << r }
>
> #action
> Intermediate.search_results(@attributes, &@block)
>
> # expectation
> @results.should == [@search_result]
>
>
> However, what I actually need to do is check each result that is
> yielded by the Connector.each_result method and compare it to the
> previous one.  If they are sufficiently similar I need to merge them
> (and same again if the next result is sufficiently similar). I only
> want to yeild merged results and results that are not similar to
> their preceeding result(s) - I'd imagined he code to do this would be
> something along the lines of:
>
> class Intermediate
>    def self.results(attributes)
>      @saved_result = nil
>
>      Connector.each_result(attributes) do |result|
>        if results_match(result, @saved_result)
>          @saved_result.merge!(result)
>        else
>          yield @saved_result unless @saved_result.nil?
>          @saved_result = result
>        end
>      end
>      yield @saved_result unless @saved_result.nil?
>    end
>
>    def results_match(this, last)
>      return false if last.nil?
>      ....
>    end
> end
>
> I can't for the life of me see how I should spec this though, as trying:
>
> Connector.stub!(:results).and_yield(@result1, @result2)
>
> is expecting the two results to be yielded at the same time and not
> sequentially.

I'm pretty sure you can get what you want by using should_receive
instead of stub and doing this:

Connector.should_receive(:results).and_yield(@result1)
Connector.should_receive(:results).and_yield(@result2)

> I can't see how to stub a method to yield sequential
> results so I can spec the behavior for different scenarios of
> similarities between subsequent results.  Is it possible to do this?
>
> Any help would be much appreciated
>
> Cheers
>
> Rupert
>
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users
>


More information about the rspec-users mailing list