On 12 Aug 2007, at 14:38, David Chelimsky wrote:
> On 8/12/07, rupert <[EMAIL PROTECTED]> 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 == [EMAIL PROTECTED]
>>
>>
>> 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)
Thanks for getting back so quickly - on a Sunday too!! Unfortunately
this doesn't seem to work - it's failing the second
Conector.should_receive spec. This seems to be because the Connector
is only receiving the results (sorry for the confusion - it should be
each_result) method call once. So what's happening is that @result1
is being yielded then the second should_receive fails as the method
isn't called a 2nd time.
So what I need to be able to say is:
Connector.should_receive(:each_result).once.and_yield(@result1
followed_by @result2 followed_by @result3)
so one call to a method can yield a set of results in turn. Hope
this makes sense (and it's not just that I'm missing the obvious or
doing something stupid!)
Cheers
Rupert
_______________________________________________
rspec-users mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/rspec-users