I have this projects controller brief action.
projects_controller.rb
def brief
##project before_filter_da ataniyor
if #project.user_allowed_to_view_brief?(current_user)
#brief_notes = #project.brief_notes.order(:id)
#project_files = #project.project_files
render :action => :written_brief if #project.project_type.brief_template == :written
else
render :action => :hidden_brief
end
end
And this is my projects_controller_spec.rb file
context 'get :brief' do
it 'should be loaded successfully' do
sign_in #creative
#project.stub(:user_allowed_to_view_brief?).with(#creative).and_return(false)
get :brief, :id => #project.to_param
response.should render_template("hidden_gallery")
end
end
and When I run this test, I encounter the error like that.
Failure/Error: response.should have_rendered("hidden_gallery")
expecting <"hidden_gallery"> but rendering with <"shared/_project_title, shared/_project_header, shared/_project_buttons, shared/_messages, projects/_brief, projects/brief, shared/_header, shared/_footer, layouts/application">
# ./spec/controllers/projects_controller_spec.rb:63:in `block (3 levels) in <top (required)>'
I think that the last line of your spec should instead read:
response.should render_template("hidden_brief")
Related
I am trying to write a controller spec to test that the right partial is rendering after a post request.
Here is the controller method being posted to:
def lookup
#guest = Guest.where("mobile_number = ?", params[:lookup_mobile_phone_number]).first_or_initialize do |g|
g.mobile_number = params[:lookup_mobile_phone_number]
end
if #guest.new_record?
#visit = Visit.new(hotel_id: params[:hotel_id])
render partial: "guests/form"
else
#visit = Visit.new(guest_id: #guest.id, hotel_id: params[:hotel_id])
render partial: "visits/form"
end
end
Here is the spec/controllers/guests_controller_spec.rb I wrote that is failing:
RSpec.describe GuestsController, :type => :controller do
describe "#lookup" do
render_views
let!(:returning_guest) { create(:test_guest) }
context "when guest is already registered with hotel" do
it "renders visits/form" do
post :lookup, :guest => { :lookup_mobile_phone_number => "5553331212"}
expect(response).to render_template(:partial => 'visits/form')
end
end
end
end
Here is the factory I'm using for :test_guest
FactoryGirl.define do
factory :test_guest, :class => 'Guest' do
name 'Jack Guest'
mobile_number '5553331212'
end
end
This is the response I am getting when the test fails
1) GuestsController#lookup when guest is already registered with hotel renders visits/form
Failure/Error: expect(response).to render_template(:partial => 'visits/form')
expecting partial <visits/form> but action rendered <["shared/_hotel_agent_name", "_hotel_agent_name", "guests/_form", "_form"]>.
Expected {"shared/_hotel_agent_name"=>1, "_hotel_agent_name"=>1, "guests/_form"=>1, "_form"=>1} to include "visits/form".
# ./spec/controllers/guests_controller_spec.rb:16:in `block (4 levels) in <top (required)>'
I've been hacking away at this a for a few days now, trying different approaches found on here with no luck. Any help would be much appreciated :)
You send
post :lookup, :guest => { :lookup_mobile_phone_number => "5553331212"}
but in controller, you use
params[:lookup_mobile_phone_number]
not
params[:guest][:lookup_mobile_phone_number]
So to fix it, according to your controller, do
post :lookup, :lookup_mobile_phone_number => "5553331212"
I am following Michael Hartl's tutorial, and trying to implement the reply twitter-like functionality, ie. "#122-john-smith: hello there" should be a reply to user 122.
I first tried filtering the "#XXX-AAA-AAA" part using a before_filter, but I decided to try it first in the very same Micropost#create action. So far I've got this MicropostController:
class MicropostsController < ApplicationController
before_filter :signed_in_user, only: [:create, :destroy]
before_filter :correct_user, only: [:destroy]
#before_filter :reply_to_user, only: [:create]
def index
end
def create
#micropost=current_user.microposts.build(params[:micropost])
#Rails.logger.info "hoooola"
regex=/\A#(\d)+(\w|\-|\.)+/i
message=#micropost.content.dup
isResponse=message.match(regex)[0].match(/\d+/)[0]
#micropost.response=isResponse
if #micropost.save
flash[:success]="Micropost created!"
redirect_to root_path
else
#feed_items=[]
render 'static_pages/home'
end
end
def destroy
#micropost.destroy
redirect_to root_path
end
private
def correct_user
#micropost = current_user.microposts.find_by_id(params[:id])
redirect_to root_path if #micropost.nil?
end
def reply_to_user
regex=/\A#(\d)+(\w|\-|\.)+/i
#I use [0] cause the output of match is a MatchData class with lots of bs
mtch=params[:micropost][:content].match(regex)[0]
#puts mtch
##micropost=current_user.microposts.build(params[:micropost])
if mtch != nil
user_id=mtch.match(/\d+/)[0]
#replied_user=User.find(user_id)
#micropost.response=user_id unless #replied_user.nil?
end
end
end
And this is the snippet test I'm trying to pass:
require 'spec_helper'
describe "MicropostPages" do
subject { page }
let(:user) { FactoryGirl.create(:user) }
before { valid_signin user }
describe "micropost creation" do
before { visit root_path }
describe "with invalid information" do
it "should not create a micropost" do
expect { click_button "Post" }.should_not change(Micropost,
:count)
end
describe "error messages" do
before { click_button "Post" }
it { should have_content('error') }
end
end
describe "with valid information" do
before { fill_in 'micropost_content', with: "Lorem ipsum" }
it "should create a micropost" do
expect { click_button "Post" }.should change(Micropost,
:count).by(1)
end
end
end
...
end
If I run these tests I get the follwing error:
Failures:
1) MicropostPages micropost creation with invalid information should not create a micropost
Failure/Error: expect { click_button "Post" }.should_not change(Micropost, :count)
NoMethodError:
undefined method `[]' for nil:NilClass
# ./app/controllers/microposts_controller.rb:14:in `create'
# (eval):2:in `click_button'
# ./spec/requests/micropost_pages_spec.rb:11:in `block (5 levels) in <top (required)>'
# ./spec/requests/micropost_pages_spec.rb:11:in `block (4 levels) in <top (required)>'
2) MicropostPages micropost creation with invalid information error messages
Failure/Error: before { click_button "Post" }
NoMethodError:
undefined method `[]' for nil:NilClass
# ./app/controllers/microposts_controller.rb:14:in `create'
# (eval):2:in `click_button'
# ./spec/requests/micropost_pages_spec.rb:14:in `block (5 levels) in <top (required)>'
However if I modify the tests and comment out all the #XXX filtering in the Micropost#create action:
def create
#micropost=current_user.microposts.build(params[:micropost])
#Rails.logger.info "hoooola"
#regex=/\A#(\d)+(\w|\-|\.)+/i
#message=#micropost.content.dup
#isResponse=message.match(regex)[0].match(/\d+/)[0]
##micropost.response=isResponse
if #micropost.save
flash[:success]="Micropost created!"
redirect_to root_path
else
#feed_items=[]
render 'static_pages/home'
end
end
The tests pass just fine and the new Micropost is not a Nil object.
It can't seem to find an explanation here.
The error comes from this line:
isResponse=message.match(regex)[0].match(/\d+/)[0]
Check if your two match calls actually match correctly. If the pattern is not found in your string, nil is returned and the [0] call is made on nil. There's two instances in this line alone where this could happen.
Try to spread it out over several lines and check the return values of your matches or extend your Regex to properly check the pattern in one go.
I'm just starting to use RSpec with a new project (after being a minitest user for a while). I've created a single MVC, called contracts. Here is the model file:
class Contract < ActiveRecord::Base
attr_accessible :name, :number, :plannedStart, :actualStart, :plannedCompletion, :actualCompletion
end
I've got a basic factory defined for Contracts (it was slightly more complex earlier, using sequence to generate novel names and numbers, but I removed all of that to try to simplify squashing this bug):
FactoryGirl.define do
factory :contract do
end
end
Here are the specs (pretty much auto generated, except I added in the calls to the factory):
require File.dirname(__FILE__) + '/../spec_helper'
describe ContractsController do
render_views
it "index action should render index template" do
create(:contract)
get :index
response.should render_template(:index)
end
it "show action should render show template" do
create(:contract)
get :show, :id => Contract.first
response.should render_template(:show)
end
it "new action should render new template" do
get :new
response.should render_template(:new)
end
it "create action should render new template when model is invalid" do
Contract.any_instance.stubs(:valid?).returns(false)
post :create
response.should render_template(:new)
end
it "create action should redirect when model is valid" do
Contract.any_instance.stubs(:valid?).returns(true)
post :create
response.should redirect_to(contract_url(assigns[:contract]))
end
it "edit action should render edit template" do
create(:contract)
get :edit, :id => Contract.first
response.should render_template(:edit)
end
it "update action should render edit template when model is invalid" do
create(:contract)
Contract.any_instance.stubs(:valid?).returns(false)
put :update, :id => Contract.first
response.should render_template(:edit)
end
it "update action should redirect when model is valid" do
create(:contract)
create(:contract)
Contract.any_instance.stubs(:valid?).returns(true)
put :update, :id => Contract.first
response.should redirect_to(contract_url(assigns[:contract]))
end
it "destroy action should destroy model and redirect to index action" do
create(:contract)
contract = Contract.first
delete :destroy, :id => contract
response.should redirect_to(contracts_url)
Contract.exists?(contract.id).should be_false
end
end
When I run the spec, I get the following error message, but the number of these I get varies from run to run:
ActiveRecord::RecordInvalid: Validation failed:
./spec/controllers/contracts_controller_spec.rb:39:in `block (2 levels) in <top (required)>'
ActiveRecord::RecordInvalid: Validation failed:
./spec/controllers/contracts_controller_spec.rb:45:in `block (2 levels) in <top (required)>'
ActiveRecord::RecordInvalid: Validation failed:
./spec/controllers/contracts_controller_spec.rb:7:in `block (2 levels) in <top (required)>'
10 examples, 3 failures, 7 passed
Finished in 0.360139 seconds
/Users/jlee/.rvm/rubies/ruby-1.9.3-p194/bin/ruby -S rspec ./spec/controllers/contracts_controller_spec.rb ./spec/models/contract_spec.rb failed
I've implemented Databasecleaner just to make sure this wasn't some odd behavior problem relating to using transactions during testing, but to no avail. Suggestions? I have no validations defined, so its hard to understand how I could be failing validation.
The stub for :valid? hangs around between tests, so I put the following in the before(:each) block: Contract.any_instance.unstub(:valid?), and it cleared everything up.
I've got the following Rspec tests that test whether a user can successfully update a scavenger hunt. I know the site will let the user do this, but my problem is that my tests aren't capturing that. Each time I run rspec, all the tests below fail. I'm hoping there's just one simple thing that I'm forgetting to put in there, but my eyes are bleary all the code's running together. When you look at these tests, does anything strike you as obviously wrong?
describe "PUT 'update'"
before(:each) do
#hunt = FactoryGirl.create(:hunt)
end
....
describe "as an admin user" do
before(:each) do
admin = FactoryGirl.create(:user, :email => "admin#example.com", :admin => true)
test_sign_in(admin)
end
....
describe "success" do
before(:each) do
#attr = { :name => "New Hunt" }
end
it "returns http success" do
get 'edit', :id => #hunt
response.should be_success
end
it "should change the hunt's name" do
put :update, :id => #hunt, :name => #attr
#hunt.reload
#hunt.name.should == #attr[:name]
end
it "should redirect to the hunt show page" do
put :update, :id => #hunt
response.should redirect_to(#hunt)
end
it "should have a flash message" do
put :update, :id => #hunt, :user => #attr
flash[:success].should =~ /updated/
end
end
...
end
Here's code from my controller.
def edit
#hunt = Hunt.find(params[:id])
#title = "Edit hunt"
end
def update
#hunt = Hunt.find(params[:id])
if #hunt.update_attributes(params[:hunt])
flash[:success] = "Hunt updated."
redirect_to hunts_path
else
#title = "Edit Hunt"
render 'edit'
end
end
And here's the feedback I'm getting form Rspec. It's all across the boards, but I'm hoping it's caused by a single problem and not four individual ones.
1) HuntsController PUT 'update' as an admin user failure should render the 'edit' page
Failure/Error: response.should render_template('edit')
expecting <"edit"> but rendering with <"">
# ./spec/controllers/hunts_controller_spec.rb:220:in `block (5 levels) in <top (required)>'
2) HuntsController PUT 'update' as an admin user failure should have the right title
Failure/Error: response.should have_selector("title", :content => "Edit hunt")
expected following output to contain a <title>Edit hunt</title> tag:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body>You are being redirected.</body></html>
# ./spec/controllers/hunts_controller_spec.rb:226:in `block (5 levels) in <top (required)>'
3) HuntsController PUT 'update' as an admin user success should change the hunt's name
Failure/Error: #hunt.name.should == #attr[:name]
expected: "New Hunt"
got: "Hunt 9" (using ==)
# ./spec/controllers/hunts_controller_spec.rb:244:in `block (5 levels) in <top (required)>'
4) HuntsController PUT 'update' as an admin user success should redirect to the hunt show page
Failure/Error: response.should redirect_to(#hunt)
Expected response to be a redirect to <http://test.host/hunts/649> but was a redirect to <http://test.host/hunts>
# ./spec/controllers/hunts_controller_spec.rb:249:in `block (5 levels) in <top (required)>'
Here is the rspec code for testing show in customers controller:
it "'show' should be successful" do
#category = Factory(:category)
#sales = Factory(:user)
#customer = Factory(:customer, :category1_id => category.id, :sales_id => sales.id)
category = mock_model('Category')
sales = mock_model('User')
customer = mock_model(Category, :sales_id => sales.id, :category1_id => category.id)
get 'show' , :id => customer.id
response.should be_success
end
Here is the error in rspec:
CustomersController GET customer page 'show' should be successful
Failure/Error: get 'show' , :id => customer.id
ActiveRecord::RecordNotFound:
Couldn't find Customer with id=1003
# c:in `find'
# ./app/controllers/customers_controller.rb:59:in `show'
# ./spec/controllers/customers_controller_spec.rb:50:in `block (3 levels) in <top (required)>'
The rspec test passes with the real record created by Factory (see #ed in rspec code)
What's wrong with the mock? Thanks.
The spec is failing inside the controller's action which doesn't know anything about your mocks unless you told it explicitly.
Add this to your spec, before the get statement.
Customer.should_receive(:find).and_return(customer)