RSpec with Rails 3.1rc4: spec test won't recognize <%= %> (should be simple)

In my user_sessions_controller:

class UserSessionsController < ApplicationController
before_filter :require_no_user, :only => [:create, :new]
before_filter :require_user, :only => :destroy

def new
@user_session = UserSession.new
@message = “Hello.”
end

def create
@user_session = UserSession.new(params[:user_session])
if @user_session.save
flash[:notice] = “Login successful!”
redirect_back_or_default admin_path
else
render :action => :new
end
end

def destroy
current_user_session.destroy
flash[:notice] = “Logout successful!”
redirect_back_or_default new_user_session_url
end
end

========
In views/user_sessions/new.html.erb:

Admin Login
<%= @message %>

========
In spec/views/user_sessions/new.html.erb_spec.rb:

require ‘spec_helper’

describe “user_sessions/new.html.erb” do

context “displays the admin login form” do
it “shows the title” do
render
rendered.should have_content(“Admin Login”) # this is fine
rendered.should have_content(“Hello.”) # I added this just to test
something simple, but it didn’t work
end

it "shows the form"

it "shows the button"

end

end

If I do “rails server” and check out the page in the browser, there is
the
“Hello.” just as I expect. But the spec test fails to get it… it
/should/
pass:

  1. user_sessions/new.html.erb displays the admin login form shows the
    title
    Failure/Error: rendered.should have_content(“Hello.”)
    expected there to be content “Hello.” in “Admin Login\n\n\n\n”

    ./spec/views/user_sessions/new.html.erb_spec.rb:9:in `block (3

levels) in <top (required)>’

So why might the <%= %> not be properly showing the @message?

I actually originally had the form code in the view:
<%= form_for @user_session, :url => user_session_path do |f| %>
<%= f.label :login %>
<%= f.text_field :login, :id=>“admin_login” %>

<%= f.label :password %>
<%= f.password_field :password, :id=>“admin_password” %>

<%= f.submit “Login”, :id=>“admin_login_button” %>
<% end %>

… but testing for this yielded
Failure/Error: render
ActionView::Template::Error:
undefined method `model_name’ for NilClass:Class

So the @user_session variable wasn’t being recognized by the spec test.
Similar problem?

Assistance is appreciated.

On Jun 29, 11:07am, David Z. [email protected] wrote:

def destroy
Admin Login
it “shows the title” do

<%= f.submit “Login”, :id=>“admin_login_button” %>
Assistance is appreciated.
This is not really an rspec issue, but a rails view testing issue.
When you render a view directly in a test, it does not use the
associated controller, and it is up to you to set up the instance
variables needed by the view. In this case:

it “shows the title” do
assign(:message, “Hello.”)
render
rendered.should have_content(“Admin Login”)
rendered.should have_content(“Hello.”)
end

HTH,
David

Thank you very much! So I guess it was a simple issue.

But what would I do for the form_for @user_session? I tried…

before(:each) do
  assign(:user_session, mock_model("UserSession").as_new_record)
end

But that returns the error:

Failure/Error: assign(:user_session,
mock_model(“UserSession”).as_new_record)
ArgumentError:
The mock_model method can only accept as its first argument:
* A String representing a Class that does not exist
* A String representing a Class that extends
ActiveModel::Naming
* A Class that extends ActiveModel::Naming

   It received UserSession

Is this because I’m using Authlogic and the UserSession model
extends Authlogic::Session::Base? How would I work around this?

On Jun 29, 12:16pm, David Z. [email protected] wrote:

Failure/Error: assign(:user_session,
extends Authlogic::Session::Base? How would I work around this?
Don’t use mock_model :slight_smile: You can use a standard test double:

assign(:user_session, double(“UserSession”))

or a real UserSession object if it’s not complicated to set up.

HTH,
David

…That’s odd. I just read The RSpec Book, and it explains how double
isn’t
sufficient when you’re testing something related to form_for. The book,
in
its example, says to use mock_model(“Message”).as_new_record…
and anyway in my case neither method is working. If I use mock_model, I
get

Failure/Error: assign(:user_session,
mock_model(“UserSession”).as_new_record)
ArgumentError:
The mock_model method can only accept as its first argument:
* A String representing a Class that does not exist
* A String representing a Class that extends
ActiveModel::Naming
* A Class that extends ActiveModel::Naming

   It received UserSession

…and if I use double, I get the error the book says I’d get:
“undefined
method `model_name’ for RSpec::Mocks::Mock:Class”

:confused: so I wonder what the best way to test form_for is now with rspec…
btw
I’m using Capybara.

On Jun 29, 1:46pm, David Z. [email protected] wrote:

* A String representing a Class that does not exist
* A String representing a Class that extends ActiveModel::Naming
* A Class that extends ActiveModel::Naming

It received UserSession

…and if I use double, I get the error the book says I’d get: “undefined
method `model_name’ for RSpec::Mocks::Mock:Class”

:confused: so I wonder what the best way to test form_for is now with rspec… btw
I’m using Capybara.

Didn’t realize you needed it for form_for. You’ll need to either use
the real object, or stub out all the necessary methods yourself (or
submit a patch to Authlogic to get it to conform to ActiveModel’s
API).

Cheers,
David

Thanks again - I just used the model directly.