Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RSpec controller testing: missing template on create

I have an interesting situation. I am testing the following simple create action:

# will only be accessed via Ajax 
def create
 click = Click.new(params[:click])
 click.save # don't really care whether its success or failure
end

Then I have the following very simple controller spec:

require 'spec_helper'

describe ClicksController, "creating a click" do
  it "should create a click for event" do
    xhr :post, :create, :click => {:event_id => 1}
    # more test to come...
  end
end

Seems trivial, yet I get the following:

Missing template clicks/create

Any tips would be appreciated.

like image 384
alexs333 Avatar asked Aug 17 '12 03:08

alexs333


4 Answers

Add to the controller action:

render :nothing => true

This one will automatically create the appropriate server's respone. More here

like image 146
megas Avatar answered Nov 17 '22 06:11

megas


You will get this error if your controller renders only JSON or XML, yet you don't specify a format in the spec; your request then defaults to unsupported HTML. In that case, simply specify the supported format when you invoke the controller method from your spec. For example, change this:

post :create, registration: @user_hash

to this:

post :create, registration: @user_hash, format: :json
like image 5
Jason Avatar answered Nov 17 '22 07:11

Jason


If you do not render anything in a controller action, rails will attempt to default to rendering a template (in this case clicks/create). I'd suggest rendering back at least a success message like so:

render :json => {:success => true}

like image 2
cjhveal Avatar answered Nov 17 '22 06:11

cjhveal


Building on megas's answer, if you're looking to test a controller action that's only accessed via a UJS link and only has a .js.erb template, I'd put this in the controller to avoid breaking your UJS functionality:

respond_to do |f|
  f.html { render nothing: true } # prevents rendering a nonexistent template file
  f.js # still renders the JavaScript template
end

This will enable you to call the controller action by simply calling ActionController::TestCase::Behavior's get/post/put/delete methods instead of needing to call xhr, because it will successfully call the method, render nothing, and continue on, while leaving your UJS behavior intact.

like image 1
Elle Mundy Avatar answered Nov 17 '22 06:11

Elle Mundy