为控制器的 before_filter 操作编写规范
Writing spec for before_filter action for a controller
我的控制器是这样的:
before_filter: check_login_status
def check_login_status
send_response(:not_logged_in) unless user.logged_in?
end
我对此的规范如下:
it 'returns error unless user is not logged in' do
expect(controller).to receive(:send_response).with(:not_logged_in)
controller.send(:check_login_status)
end
现在我想写另一个测试:
it 'checks the login status of user before any action' do
.......
end
我怎样才能完成第二个测试?
您不测试回调 - 您测试行为。
回调是控制器的内部实现细节,并作为私有方法实现(或者至少应该是,如果你做得对的话)。您应该测试应用程序的行为,而不是它如何完成工作。
为了测试身份验证,您需要编写一个请求规范,您可以在其中向端点发送一个真实的 HTTP 请求并编写关于以下内容的期望:
- 返回的状态码是否正确?
- 是否重定向了用户?
- 有没有发生不该发生的副作用?例如正在创建、销毁或更新的记录。
- 用户是否得到了他们不应该得到的任何信息?
一个例子:
require 'spec_helper'
RSpec.describe "Things", type: :request do
describe "POST /things" do
context "when not logged in" do
let(:action) do
post '/things', params: { thing: { foo: 'bar' }}
end
it "does not allow a thing to be created" do
expect{ action }.to_not change(Thing, :count)
end
it "redirects the user to the login page" do
action
expect(response).to redirect_to '/login'
end
# etc
end
end
end
这种测试可能有些重复和乏味 - 共享示例可以帮助解决这个问题。
或者,您可以正确执行身份验证系统,这样它实际上会引发异常,您可以通过禁用 rescue_from 来测试引发的异常。事实上,您很想往里面一探究竟,这实际上可能是在揭示设计的味道。
我的控制器是这样的:
before_filter: check_login_status
def check_login_status
send_response(:not_logged_in) unless user.logged_in?
end
我对此的规范如下:
it 'returns error unless user is not logged in' do
expect(controller).to receive(:send_response).with(:not_logged_in)
controller.send(:check_login_status)
end
现在我想写另一个测试:
it 'checks the login status of user before any action' do
.......
end
我怎样才能完成第二个测试?
您不测试回调 - 您测试行为。
回调是控制器的内部实现细节,并作为私有方法实现(或者至少应该是,如果你做得对的话)。您应该测试应用程序的行为,而不是它如何完成工作。
为了测试身份验证,您需要编写一个请求规范,您可以在其中向端点发送一个真实的 HTTP 请求并编写关于以下内容的期望:
- 返回的状态码是否正确?
- 是否重定向了用户?
- 有没有发生不该发生的副作用?例如正在创建、销毁或更新的记录。
- 用户是否得到了他们不应该得到的任何信息?
一个例子:
require 'spec_helper'
RSpec.describe "Things", type: :request do
describe "POST /things" do
context "when not logged in" do
let(:action) do
post '/things', params: { thing: { foo: 'bar' }}
end
it "does not allow a thing to be created" do
expect{ action }.to_not change(Thing, :count)
end
it "redirects the user to the login page" do
action
expect(response).to redirect_to '/login'
end
# etc
end
end
end
这种测试可能有些重复和乏味 - 共享示例可以帮助解决这个问题。
或者,您可以正确执行身份验证系统,这样它实际上会引发异常,您可以通过禁用 rescue_from 来测试引发的异常。事实上,您很想往里面一探究竟,这实际上可能是在揭示设计的味道。