12

I want to check if a method was called exactly(n) times, but I still want that method to perform its original function. Consider a simple thumbnailing system that caches the thumbnail file and make sure ImageMagick's "convert" executable that creates the thumbnail is only called on the first request.

  it "this passes: should detect a cached version" do
    thumbnail_url = thumbnail_url_for("images/something.jpg")
    get thumbnail_url
    last_response.should be_ok
    Sinatra::Thumbnail.should_not_receive(:convert)
    get thumbnail_url
    last_response.should be_ok
  end

  it "this fails:  should detect a cached version" do
    Sinatra::Thumbnail.should_receive(:convert).exactly(1).times
    thumbnail_url = thumbnail_url_for("images/something.jpg")
    get thumbnail_url
    last_response.should be_ok
    get thumbnail_url
    last_response.should be_ok
 end

In my case I get away with my first attempt, but there could be cases where I don't. The second one fails because the call Thumbnail.convert is detected but the method itself doesn't do anything. Is there some way to just detect the call to the method and have it do it's original thing?

BTW: I suspect this question is very similar, but then I get lost in the description and also it's unanswered...

Community
  • 1
  • 1
joao
  • 3,517
  • 1
  • 31
  • 43

2 Answers2

21

Now there's an and_call_original method precisely for this use case. (RSpec 2.12)

Sinatra::Thumbnails.should_receive(:convert).and_call_original

The documentation can be found on the same page referenced by Joao, here.

See also: the changelog

kpassa615
  • 333
  • 3
  • 7
15

Yay! I think I figured it out!

it "should detect a cached version" do
  original_method = Sinatra::Thumbnails.method(:convert)
  Sinatra::Thumbnails.should_receive(:convert).exactly(1).times do |*args|
    original_method.call(*args)
  end
  thumbnail_url = thumbnail_url_for("images/something.jpg") # 
  get thumbnail_url
  last_response.should be_ok
  get thumbnail_url
  last_response.should be_ok
end

It's documented (poorly, in my opinion) in here at the very end...

joao
  • 3,517
  • 1
  • 31
  • 43
  • the documentation is indeed poor, and I can't find any mentioning of `original_method` in the page you pointed to. But thanks for the answer! – lulalala Nov 21 '11 at 01:38
  • `original_method` is just a local variable I used! The page I linked to mentions "arbitrary handling", which is what I needed to call the method stored in that local variable. – joao Dec 05 '11 at 15:13
  • This answer is out of date. See @kpassa615's answer. – Marc-André Lafortune May 17 '13 at 22:57
  • Ok, updated the accepted answer since rspec caught up. Downvoting was slightly mean though... – joao May 18 '13 at 10:15