I suspect I just being very dumb with this and missing something obvious. But I fairly new to rspec and factory girl and cannot get this simple test to work.
Basically I have set up a model called page and am calling it in the controller like this:
#pages = Page.where(:page_type => "homepage").limit(2)
for in my test I do the following:
before do
#pages = [Factory(:page), Factory(:page, :title=> "Contact", :content=>"contact content", :meta=>"meta content", :page_type=>'homepage') ]
get 'index'
end
it 'should set the pages variable' do
assigns[:pages].should_not be_nil
assigns[:pages].length == 2;
end
yet all I get is:
Failure/Error: assigns[:pages].should_not be_nil
expected not nil, got nil
ANy help greatly appreciated
Your controller is setting its #pages instance variable to nil. Most likely it's not being assigned to at all. Are you sure the code snippet which you pasted:
#pages = Page.where(:page_type => "homepage").limit(2)
is being called in the index action of your controller? If so, that code would set #pages to the empty list, not nil.
Related
so i need to test a partial. the partial is rendered by specific action, its something like messages box in facebook. my test looks like this:
describe 'partials/_partial.js.erb' do
it 'displays stuff' do
render
end
end
i run it, and i know it does what i want because i immediately get
Failure/Error: if #items.count > 0
ActionView::Template::Error:
undefined method `count' for nil:NilClass
i do not need to hear that it is a bad practice to use instance vars in a partial, it is already there and i need to work with it. so how do i set #items here...?
UPDATE:
controller action looks like this:
def controller_method
#items = items_method
render_version(:partial => "partials/_partial.js.erb")
end
It looks like you're using rspec. In that case, any instance variables you define during your test will be available for your views (regardless if it's a partial or not).
describe "users/_messages" do
before(:each) do
# This is available in your view.
#items = []
end
it "renders without error when #items is empty" do
# Will pass, #items is available
expect { render }.to_not raise_error
end
it "shows a count of how many messages there are" do
# You can modify it before rendering
#items << Message.new
render
expect(rendered).to have_content "You have 1 message"
end
end
I have controller action like
def get_status
status_name = current_user.status
status_updated_time = current_user.updated_at
render :partial => 'show_status', :locals => {status_name: status_name, status_updated_time: status_updated_time}
end
here I am planning to test local variable values which are passing via render partial. i.e
status_name, status_updated_time.
Could you please let me know how to write rspecs for render partial with locals in controller.
I would move variable logic into a separate method:
def get_status
render partial: 'show_status', locals: get_status_from(current_user)
end
protected
def get_status_from(user)
{ status_name: user.status, status_updated_time: user.updated_at }
end
and test that method instead.
I would say that to test the controller, what you're after is a basic feature/integration spec wherein you can simply look for the content held by your partial.
feature 'SomeController' do
background do
# setup data
# and anything else you need for authentication, etc. as your site dictates
end
scenario 'viewing the get status page' do
visit some_controller_get_status_path
expect(page).to have_text('WHATEVER IS IN THE LOCAL VAR')
end
end
I prefer to use feature specs over controller specs as I seek (but often fail!) to keep my controllers so simple that there is not really much to test in them. With feature specs, I feel like I'm getting more from the test in terms of how my app works, etc.
EDIT: sorry ... hit enter too early :).
For a controller, you could directly test the var value along the lines of:
describe "Your Controller", :type => :controller do
describe "GET get_stuff" do
it "assigns a value to status_name" do
get :get_status
expect(assigns(:status_name)).to eq(['VALUE'])
end
end
end
That may not be 100% spot-on for a controller spec (again, I don't use them a lot) but I think it should get you on your way should you go controller spec over feature/integration spec.
you could do something like
it "should render correct partial for get_status" do
controller.should_receive(:render).with({
:partial => '_show_status', #here you will have to give the full path like <controller_name>/_show_status
:locals => {status_name: <name>, status_update_time: <time>}
})
get 'get_status'
end
I have an rspec test in which I need to test my controller.
it "renders the #show view" do
get :show, id: FactoryGirl.create(:quiz)
#facebook_profile = FactoryGirl.create(:facebook_profile)
response.should render_template :show
end
The facebook_profile object has a user_q1 column, so #facebook_profile.user_q1 gives a valid result.
In my quiz controller:
#user_q1 = #facebook_profile.user_q1
This works fine in manual testing, but in rspec, I get the result:
undefined method `user_q1' for nil:NilClass
I suspect the issue is here, in the first line of my show method in the controller:
#facebook_profile = FacebookProfile.find_by_facebook_id(session[:facebook_profile_id])
I have a variable in my session controller (although not a column in any model) that I call facebook_profile_id. I then call this variable in the above line of code in my quiz controller. I think my spec can't define #facebook_profile because it doesn't know facebook_profile_id. Apparently just defining "#facebook_profile = FactoryGirl" (like I have above) doesn't work.
You should proceed this way:
let(:fb_profile) { FactoryGirl.create(:facebook_profile) }
let(:quiz) { FactoryGirl.create(:quiz) )
it "renders the #show view" do
FacebookProfile.should_receive(:find_by_facebook_id).and_return fb_profile
get :show, id: quiz.id
response.should render_template :show
end
Actually you don't need to create objects in db, but that's another debate.
I am trying to mock out the session hash for a controller like so:
it "finds using the session[:company_id]" do
session.should_receive(:[]).with(:company_id).and_return 100
Company.should_receive(:find).with(100)
get 'show'
end
When I call get 'show' it states:
received :[] with unexpected arguments
expected: (:company_id)
got: ("flash")
The controller code looks like:
def show
company_id = session[:company_id]
#company = Company.find params[company_id]
end
I have also simply tried setting
it "finds using the session[:company_id]" do
session[:company_id]= 100
Company.should_receive(:find).with(100)
get 'show'
end
but then get an issue about:
expected: (100)
got: (nil)
Anyone have ideas why?
I just ran into this. I couldn't manage to get should_receive to not interfere with the flash stuff.
But this let me test the behavior I was looking for:
it "should redirect to intended_url if set" do
request.env['warden'] = double(:authenticate! => true)
session.stub(:[]).with("flash").and_return double(:sweep => true, :update => true, :[]= => [])
session.stub(:[]).with(:intended_url).and_return("/users")
post 'create'
response.should redirect_to("/users")
end
Hope that helps...
I could not figure out how to mock the session container itself, however in most cases simply passing session data with request should be enough. So the test would split into two cases:
it "returns 404 if company_id is not in session" do
get :show, {}, {}
response.status.should == 404 # or assert_raises depending on how you handle 404s
end
it "finds using the session[:company_id]" do
Company.should_receive(:find).with(100)
get :show, {}, {:company_id => 100}
end
PS: forgot to mention I'm using some customized helpers from this snippet.
try this:
session.expects(:[]).with(has_entries('company_id' => 100))
It's because you fetch flash session from your controller. So define it. Flash is save in session.
it "finds using the session[:company_id]" do
session.stub!(:[]).with(:flash)
session.should_receive(:[]).with(:company_id).and_return 100
Company.should_receive(:find).with(100)
get 'show'
end
I have the following RSpec example which is passing:
describe UsersController do
it "should render new template on new action" do
get :new
response.should render_template("users/new")
end
end
The problem is I have not implemented the 'new' action on the UsersController.
Can anyone tell me why this test is passing?
I am new to RSpec, so any tips would be greatly appreciated!
When requesting an action for which a view exists, but the action is not defined, Rails will simply render the view. Therefore your spec (correctly) passes.
In addition to this spec, you may want to test for the assignment of particular instance variables. Example:
it "should assign the found articles for the view" do
assigns[:article].should == [#article]
end