如何期望加薪ActiveRecord::RecordNotFoundrspec?
How to expect raise ActiveRecord::RecordNotFound rspec?
这个错误如何通过测试?
Rspec 控制器和结果
context 'invalid confirmation_token' do
subject do
post signup_step5_path,
params: {
user: {
password: 'hoge',
password_confirmation: 'hoge',
confirmation_token: 'wrong_token'
}
}
end
let(:user) { User.find_by(confirmation_token: 'testtesttest') }
it 'does not update user attributes and never create an end_point record' do
expect { subject }.raise_error(ActiveRecord::RecordNotFound)
expected ActiveRecord::RecordNotFound but nothing was raised
控制器方法
我拯救ActiveRecord::RecordNotFound并在私有方法中渲染404页面。
class Users::SignupController < ApplicationController
layout 'devise'
rescue_from ActiveRecord::RecordNotFound, with: :render404
def step5
@user = User.find_by(confirmation_token: step5_params[:confirmation_token])
raise ActiveRecord::RecordNotFound unless @user
.....
end
private
def render404(error = nil)
logger.info "Rendering 404 with exception: #{error.message}" if error
render file: Rails.root.join('public/404.ja.html'), status: :not_found
end
end
假设它是 request spec,请求将 return HTTP 404,您可以为此设置期望值:
is_expected.to be_not_found
旁注:
@user = User.find_by(confirmation_token: step5_params[:confirmation_token])
raise ActiveRecord::RecordNotFound unless @user
可以简化为:
@user = User.find_by!(confirmation_token: step5_params[:confirmation_token])
首先解释异常匹配器实际上只会匹配未捕获的异常可能是个好主意。那是因为它基本上只是一个救援语句,并在调用堆栈冒泡时拯救异常,它旨在测试一段代码是否引发了一个由消费者捕获的异常——这是测试 行为.
另一方面,测试代码引发和挽救异常是测试它如何工作。
def foo
raise SomeKindOfError
end
def bar
begin
raise SomeKindOfError
rescue SomeKindOfError
puts "RSpec will never catch me!"
end
end
describe "#foo" do
it "raises an exception" do
expect { foo }.to raise_exception(SomeKindOfError)
end
end
describe "#bar" do
it "rescues the exception" do
expect { bar }.to_not raise_exception(SomeKindOfError)
end
end
当您使用 rescue_from
时,它基本上只是使用 around_action 回调来挽救给定异常的语法糖:
class ApplicationController
around_action :handle_errors
private
def handle_errors
begin
yield
rescue SomeKindOfError
do_something
end
end
end
虽然 RSpec 曾经有过 bypass_rescue
控制器规格,但 Rails 和 RSpec 团队和您都非常不鼓励使用控制器规格我们实际上只是在测试实现而不是行为。
相反,您应该测试实际控制器做了什么,而不是它是如何做的。
context 'invalid confirmation_token' do
# explicit use of subject is a code smell
before do
post signup_step5_path,
params: {
user: {
password: 'hoge',
password_confirmation: 'hoge',
confirmation_token: 'wrong_token'
}
}
end
let(:user) { User.find_by(confirmation_token: 'testtesttest') }
it 'does not update the users password' do
expect(user.valid_password?('hoge')).to be_falsy
end
it 'returns a 404 - NOT FOUND' do
expect(response).to have_http_status(:not_found)
end
# using Capybara in a feature spec is a better way to do this.
it 'renders something' do
expect(response.body).to match("Oh Noes!")
end
end
这个错误如何通过测试?
Rspec 控制器和结果
context 'invalid confirmation_token' do
subject do
post signup_step5_path,
params: {
user: {
password: 'hoge',
password_confirmation: 'hoge',
confirmation_token: 'wrong_token'
}
}
end
let(:user) { User.find_by(confirmation_token: 'testtesttest') }
it 'does not update user attributes and never create an end_point record' do
expect { subject }.raise_error(ActiveRecord::RecordNotFound)
expected ActiveRecord::RecordNotFound but nothing was raised
控制器方法 我拯救ActiveRecord::RecordNotFound并在私有方法中渲染404页面。
class Users::SignupController < ApplicationController
layout 'devise'
rescue_from ActiveRecord::RecordNotFound, with: :render404
def step5
@user = User.find_by(confirmation_token: step5_params[:confirmation_token])
raise ActiveRecord::RecordNotFound unless @user
.....
end
private
def render404(error = nil)
logger.info "Rendering 404 with exception: #{error.message}" if error
render file: Rails.root.join('public/404.ja.html'), status: :not_found
end
end
假设它是 request spec,请求将 return HTTP 404,您可以为此设置期望值:
is_expected.to be_not_found
旁注:
@user = User.find_by(confirmation_token: step5_params[:confirmation_token])
raise ActiveRecord::RecordNotFound unless @user
可以简化为:
@user = User.find_by!(confirmation_token: step5_params[:confirmation_token])
首先解释异常匹配器实际上只会匹配未捕获的异常可能是个好主意。那是因为它基本上只是一个救援语句,并在调用堆栈冒泡时拯救异常,它旨在测试一段代码是否引发了一个由消费者捕获的异常——这是测试 行为.
另一方面,测试代码引发和挽救异常是测试它如何工作。
def foo
raise SomeKindOfError
end
def bar
begin
raise SomeKindOfError
rescue SomeKindOfError
puts "RSpec will never catch me!"
end
end
describe "#foo" do
it "raises an exception" do
expect { foo }.to raise_exception(SomeKindOfError)
end
end
describe "#bar" do
it "rescues the exception" do
expect { bar }.to_not raise_exception(SomeKindOfError)
end
end
当您使用 rescue_from
时,它基本上只是使用 around_action 回调来挽救给定异常的语法糖:
class ApplicationController
around_action :handle_errors
private
def handle_errors
begin
yield
rescue SomeKindOfError
do_something
end
end
end
虽然 RSpec 曾经有过 bypass_rescue
控制器规格,但 Rails 和 RSpec 团队和您都非常不鼓励使用控制器规格我们实际上只是在测试实现而不是行为。
相反,您应该测试实际控制器做了什么,而不是它是如何做的。
context 'invalid confirmation_token' do
# explicit use of subject is a code smell
before do
post signup_step5_path,
params: {
user: {
password: 'hoge',
password_confirmation: 'hoge',
confirmation_token: 'wrong_token'
}
}
end
let(:user) { User.find_by(confirmation_token: 'testtesttest') }
it 'does not update the users password' do
expect(user.valid_password?('hoge')).to be_falsy
end
it 'returns a 404 - NOT FOUND' do
expect(response).to have_http_status(:not_found)
end
# using Capybara in a feature spec is a better way to do this.
it 'renders something' do
expect(response.body).to match("Oh Noes!")
end
end