I am trying to set up the controller test to confirm that one of my instance variables (@template) receives a given function call (deliver).

With the following code, however, the assigns gets evaluated before the posts, so assigns is nil:

  it 'calls @template.deliver' do
    assigns(:template).should_receive(:deliver).and_call_original
    post :deliver, params
  end      

How can I set up this test effectively?

Tech stack:
Ruby 1.9.3p448
Rails 3.2.13
rspec-rails 2.13.1 (for the accepted answer below, I had to upgrade to 2.14)

有帮助吗?

解决方案

Assuming @template is an instance of a Template object, you may be able to use rspecs expect syntax:

it 'calls @template.deliver' do
  Template.any_instance.stub(deliver: true)

  post :deliver, params

  expect(assigns(:template)).to have_received(:deliver)
end

其他提示

The easiest seems to create your template object upfront, and then stub the Template.find method to return the object you've created, something like (using mocha in my case)

@template = ...
Template.stubs(:find).returns(@template)

You can then use the statement you've written like

@template.should_receive(:deliver).and_call_original

One way i can think of is stubbing the part that assigns template

For eg(Assuming that you have a separate test for get_template):

If you have the following deliver action

def deliver
  @template = get_template
  @template.deliver
end

And your test can be

it 'calls @template.deliver' do
  controller.should_receive(:get_template).and_return(mock_template = mock("template"))
  mock_template.should_receive(:deliver).and_call_original
  post :deliver, params
end   
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top