简体   繁体   中英

Simple controller tests with rspec rails4

I was looking into some rspec testing lately and I was wondering how to properly test controllers. My controller is fairly simple so it shouldn't be something too hard:

 class UsersController < ApplicationController
before_action :set_user, only: [:show, :edit, :update, :destroy]

# GET /users
def index
@q = User.search(params[:q])
@users = @q.result(distinct: true)
@q.build_condition if @q.conditions.empty?
@q.build_sort if @q.sorts.empty?
end

# GET /users/1
def show
end

# GET /users/new
def new
@user = User.new
end

# GET /users/1/edit
def edit
end

def archive
@q = User.search(params[:q])
@users = @q.result(distinct: true)
@q.build_condition if @q.conditions.empty?
@q.build_sort if @q.sorts.empty?
end

# POST /users
def create
@user = User.new(user_params)
if @user.save
redirect_to users_path, notice: 'Student was successfully added.'
else
render action: 'new'
end
end

# PATCH/PUT /users/1
def update
if @user.update(user_params)
redirect_to @user, notice: 'Student information was successfully updated.'
else
render action: 'edit'
end
end

# DELETE /users/1
def destroy
@user.destroy
redirect_to users_url, notice: 'Student information was successfully deleted.'
end

private
# Use callbacks to share common setup or constraints between actions.
def set_user
@user = User.find(params[:id])
end

# Only allow a trusted parameter "white list" through.
def user_params

params.require(:user).permit(:firstName, :lastName, :email, :dateOfBirth, :notes, :sex, :archive, :category => [])

end
end

So far I have written 2-3 tests but I am not sure if they even do anything:

describe 'GET #index' do
 it "displays all users" do
   get :index
 response.should be_redirect
end
end

describe 'GET #new' do
 it "creates a new user" do
   get :new
 response.should be_redirect
end
end

I tried doing the same for edit and show but they didn't work and I am not sure why (because as I said, I don't know what I am doing). Could anyone give me a few test examples for these methods or could redirect me to an rspec guide for rails4?

Are you expecting the controller #index action to redirect? Because that wouldn't be typical. I would

describe 'GET #index' do
  get 'index'
  it {expect(response).to be_success)}
end

This line...

it "displays all users" do

in a controller spec makes me wonder if your confusing controller and request specs. I did this when I first got running with testing. "Displaying all users" sounds like a request spec to me. Testing if a page redirects or response status codes is more akin to controller specs.

I found http://betterspecs.org/ to be a really helpful resource in understanding testing better.

RE: WHAT to test

This worked for me but results may vary.

Controller Specs - Don't test controllers

Controllers should be skinny so you're just testing whether Rails is working. eg an index action may contain @users = User.all or similar and very little else. What is there to test there? Nothing. If you have lots of code in your controller actions then it probably shouldn't be there. Move it out to the models. Remember: Fat models, skinny controllers. This is an example of how testing creates better code. I have very few controller specs and I think nearly all of them are double checking authorisation to pages. I only use them where there's code in the controller. Here's an example:

context "Non admin signed in" do
before(:each) do
  sign_in user
  controller.stub!(:current_user).and_return(user)
end

it {subject.current_user.should_not be_nil}
it "deny non admin access to index" do
  sign_in user
  get 'index'
  expect(response).to render_template("pages/access_denied")
end

end

Request Specs Test what you would test in a browser (20% of tests)

Imagine that you weren't doing RSpec testing. If you're like me then this is not too hard to imagine. How would you test the thing you want to build? Chances are that the first thing you'd do is load up a browser and see if something is on the page that you were expecting. That IS a request spec. It's that simple. Request specs are the automated ways of loading up a browser, clicking on a few buttons and checking what happened. Whatever it is your checking in the browser... check that same thing using Capybara. If it has Javascript on the page then you'll need Webkit or Selenium on top of Capybara to push the buttons as you would. With selenium you actually see the browser window pop up on the desktop as if a mysterious gremlin had taken control of your keyboard. Don't test anything in a request spec that you wouldn't be testing manually in a browser. That means don't check the state of other models in the database. Request specs are what the user can see. If you can't see it, don't test it.

Model specs - Test what you would test in the console (80% of tests) Before I became a good TDD/BDD boy I found I spent a lot of time loading up irb or console and making models and doing X to see if Y would happen. Automate that thing. That's a model spec. When your request spec fails (which it should at first if it's doing anything useful) then drop down into the model spec. A failing request spec might be:

it {expect(page.find('#login_box')).to have_content 'Logged in as Kevin Monk'}

from

no method full_name for instance of User

And if you weren't a TDD good boy you might load up the console and find what was happening with the full_name method.

> rails console
$> kevin  = User.find(1)
$> kevin.full_name

And then visually check that you get the full name baack but this should be done as a model spec.

I hope that helps. A problem I've had with a lot of books on testing is that the authors tend to be such experts and therefore don't appreciate that us mortals really need to understand the basic premise of what it is your supposed to be testing.

you have a typo in your spec code , you have to change respone, for response

I think that´s the problem

you can find more information in about test controllers in

https://www.relishapp.com/rspec/rspec-rails/docs/controller-specs

regards

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM