我最近正在研究一些rspec测试,我想知道如何正确测试控制器。我的控制器相当简单,所以它不应该太难:
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
到目前为止,我已经编写了2-3个测试,但我不确定他们是否做了任何事情:
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
我尝试做同样的编辑和表演,但他们没有工作,我不知道为什么(因为正如我所说,我不知道我在做什么)。 任何人都可以给我一些这些方法的测试示例,或者可以将我重定向到rails4的rspec指南吗?
答案 0 :(得分:3)
您是否期望控制器#index操作重定向?因为那不是典型的。 我会
describe 'GET #index' do
get 'index'
it {expect(response).to be_success)}
end
这一行...
it "displays all users" do
在控制器规范中让我想知道你的混淆控制器和请求规格。我第一次参加测试时就这样做了。 &#34;显示所有用户&#34;听起来像是一个请求规范给我。测试页面重定向或响应状态代码是否更类似于控制器规范。
我发现http://betterspecs.org/对于更好地理解测试非常有用。
RE:测试什么
这对我有用,但结果可能会有所不同。
控制器规格 - 不要测试控制器
控制器应该是瘦的,所以你只是测试Rails是否正常工作。例如索引操作可能包含@users = User.all或类似的内容,其他内容很少。那里有什么测试?没有。如果您的控制器操作中有很多代码,那么它可能不应该存在。将其移至模型。记住:胖子模特,瘦小的控制者。这是测试如何创建更好的代码的示例。我的控制器规格很少,我认为几乎所有这些都是对页面的双重检查授权。我只在控制器中有代码的地方使用它们。这是一个例子:
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
端
请求规范测试您在浏览器中测试的内容(20%的测试)
想象一下,你没有进行RSpec测试。如果你像我一样,那么这不难想象。你会如何测试你想要构建的东西?您可能要做的第一件事就是加载浏览器并查看页面上是否有您期望的内容。 IS 是一个请求规范。就这么简单。请求规范是加载浏览器,点击几个按钮并检查发生的事情的自动方式。无论你在浏览器中检查是什么......使用Capybara检查同样的事情。如果它在页面上有Javascript,那么你需要在Capybara顶部使用Webkit或Selenium来按下按钮。使用selenium,您实际上会看到桌面上弹出的浏览器窗口,好像一个神秘的gremlin控制了您的键盘。不要在请求规范中测试您不会在浏览器中手动测试的任何内容。这意味着不要检查数据库中其他模型的状态。请求规范是用户可以看到的。如果你看不到它,就不要测试它。
型号规格 - 测试您在控制台中测试的内容(80%的测试) 在我成为一个优秀的TDD / BDD男孩之前,我发现我花了很多时间加载irb或控制台并制作模型并做X以查看Y是否会发生。自动化那件事。这是一个型号规格。当您的请求规范失败时(如果它执行任何有用的事情,它应该首先应该),然后下拉到模型规范中。失败的请求规范可能是:
it {expect(page.find('#login_box')).to have_content 'Logged in as Kevin Monk'}
这
no method full_name for instance of User
如果你不是TDD好男孩,你可以加载控制台并找到full_name方法发生的事情。
> rails console
$> kevin = User.find(1)
$> kevin.full_name
然后直观地检查您是否获得了全名baack,但这应该作为模型规范来完成。
我希望有所帮助。我在很多关于测试的书籍中遇到的一个问题是,作者往往是这样的专家,因此不要理解我们凡人真的需要理解你应该是什么样的基本前提。测试。
答案 1 :(得分:0)
您的规范代码中有拼写错误,您必须更改respone,以获取响应
我认为这就是问题
您可以在
中找到有关测试控制器的更多信息https://www.relishapp.com/rspec/rspec-rails/docs/controller-specs
问候