I'm using Rspec and Rails 3 for testing. I've tested my models and helpers but I'm lost on how to begin testing controllers. Almost all of my data in my controller actions is pulled using something like these examples:
@services = current_account.services
@projects = current_person.projects
@projects = current_account.projects.active
# this is really @projects = current_person.account.projects.active)
I can't seem to find any examples of how to test data that's pulled this way. All of the examples I've found aren't scoped to an account or person. Can anyone point me to an article on how to mock or stub this type of arrangement? Is this a sign that this entire approach isn't correct? Below, I've included an entire sample controller.
Any help would be greatly appreciated.
Thanks, David
class ServicesController < ApplicationController
# Run authorizations
filter_resource_access
# Respond to ...
respond_to :html, :xml, :json
respond_to :js, :only => [:new, :create, :edit, :update, :destroy]
# GET /services
# GET /services.xml
def index
@services = current_account.services.order("name").paginate(:page => params[:page])
respond_with(@services)
end
# GET /services/1
# GET /services/1.xml
def show
@service = current_account.services.find(params[:id])
respond_with(@service)
end
# GET /services/new
# GET /services/new.xml
def new
@service = current_account.services.new
respond_with(@service)
end
# GET /services/1/edit
def edit
@service = current_account.services.find(params[:id])
respond_with(@service)
end
# POST /services
# POST /services.xml
def create
@service = current_account.services.new(params[:service])
if @service.save
# flash[:notice] = 'A service was successfully created.'
end
respond_with(@service, :location => services_url)
end
# PUT /services/1
# PUT /services/1.xml
def update
@service = current_account.services.find(params[:id])
if @service.update_attributes(params[:service])
# flash[:notice] = 'The service was successfully updated.'
end
respond_with(@service, :location => services_url)
end
# DELETE /services/1
# DELETE /services/1.xml
def destroy
@service = current_account.services.find(params[:id])
if @service.destroy
flash[:notice] = "The service was successfully deleted."
else
flash[:warning] = @service.errors.full_messages.inject("") { |acc, message| acc += message }
end
respond_with(@service)
end
end
–––––– UPDATE
Thanks to Xaid's solution I was able to get a solution:
context "logged_in" do
before(:each) do
@current_account = Factory.create(:account)
controller.stub!(:current_account).and_return(@current_account)
@services = FactoryGirl.create_list(:service, 10, :account => @current_account)
@services << @current_account.services.first
@current_account.services.stub!(:all).and_return(@services)
end
# INDEX
describe "GET services" do
before(:each) do
get :index
end
it "should set @services when accessing GET /index" do
assigns[:services].should == @services
end
it "should respond with success" do
response.should be_success
end
end
end
Can't you use something like this to test your 'index' action
describe "GET 'index'" do
before(:each) do
@user = FactoryGirl.create(:user)
controller.stub!(:current_user).and_return(@user)
@services = FactoryGirl.create_list(:service, 10, :user => @user)
@user.services.stub!(:all).and_return(@services)
end
it "should return a list of services" do
get :index
assigns(:services).should == @services
end
end
If I understood your question correctly, you should be able to stub current_user.services(or projects) and make it return some known value (generated by FactoryGirl in my example) and check that against the value thats stored in your action (for example, @services in your 'index' action).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.