使用 Rspec 模拟活动记录无效异常
mocking active record invalid exception with Rspec
我在 rspec 中模拟活动记录无效异常。
这是我遇到问题的方法。 image_processing_error 检查图像对象的错误。
def save_image(image)
begin
image.save!
{ message: I18n.t("messages.image_saved") , status: 200 }
rescue ActiveRecord::RecordInvalid
image_processing_error(image)
end
end
private
def image_processing_error(image = nil)
if image && image.errors.any? && image.errors.messages.any?
{ message: image.errors.messages.values[0][0] , status: 422 }
else
{ message: I18n.t("errors.invalid_request"), status: 422 }
end
end
这是我的 rspec 同样的
# frozen_string_literal: true
require "rails_helper"
RSpec.describe ImagesService do
describe ".save_image" do
context "save image throws error" do
let(:image) { double("image", { "errors": { "messages": { "name": ["is invalid", "must be implemented"]}}}) }
before do
allow(image).to receive(:save!).and_raise(ActiveRecord::RecordInvalid)
end
subject { described_class.save_image(image) }
it "raised the error" do
// I want to test the **ActiveRecord::RecordInvalid
// I places NoMethodError to just pass the test
expect { subject }.to raise_error NoMethodError
expect { subject }.to raise_error ActiveRecord::RecordInvalid
end
end
end
end
当我读取图像错误时出现以下错误。我必须让它正常工作的正确双精度值是多少。
Failures:
1) ImagesService.save_image save image throws error raised the error
Failure/Error: expect { subject }.to raise_error ActiveRecord::RecordInvalid
expected ActiveRecord::RecordInvalid, got #<NoMethodError: undefined method `messages' for {:messages=>{:name=>["is invalid", "must be implemented"]}}:Hash> with backtrace:
在这种情况下,您在调用 subject
时没有得到异常的原因是它没有引发异常。由于您在 save_image
中设置了一个救援块,如果在其中抛出异常,将调用救援块并且不会将异常传播给调用者,而是 image_processing_error
被调用。
所以在您的规范中,当您调用 subject
时,您不会得到异常,而是会从 image_processing_error
中得到解析错误,据我了解,这实际上是预期行为。
在这种情况下,您可以做的是测试从 subject
获得的结果是否与您在这种情况下收到的预期错误消息匹配,例如:
it "returns the error messages" do
expect(response.body).to include("is invalid", "must be implemented")
end
我在 rspec 中模拟活动记录无效异常。
这是我遇到问题的方法。 image_processing_error 检查图像对象的错误。
def save_image(image)
begin
image.save!
{ message: I18n.t("messages.image_saved") , status: 200 }
rescue ActiveRecord::RecordInvalid
image_processing_error(image)
end
end
private
def image_processing_error(image = nil)
if image && image.errors.any? && image.errors.messages.any?
{ message: image.errors.messages.values[0][0] , status: 422 }
else
{ message: I18n.t("errors.invalid_request"), status: 422 }
end
end
这是我的 rspec 同样的
# frozen_string_literal: true
require "rails_helper"
RSpec.describe ImagesService do
describe ".save_image" do
context "save image throws error" do
let(:image) { double("image", { "errors": { "messages": { "name": ["is invalid", "must be implemented"]}}}) }
before do
allow(image).to receive(:save!).and_raise(ActiveRecord::RecordInvalid)
end
subject { described_class.save_image(image) }
it "raised the error" do
// I want to test the **ActiveRecord::RecordInvalid
// I places NoMethodError to just pass the test
expect { subject }.to raise_error NoMethodError
expect { subject }.to raise_error ActiveRecord::RecordInvalid
end
end
end
end
当我读取图像错误时出现以下错误。我必须让它正常工作的正确双精度值是多少。
Failures:
1) ImagesService.save_image save image throws error raised the error
Failure/Error: expect { subject }.to raise_error ActiveRecord::RecordInvalid
expected ActiveRecord::RecordInvalid, got #<NoMethodError: undefined method `messages' for {:messages=>{:name=>["is invalid", "must be implemented"]}}:Hash> with backtrace:
在这种情况下,您在调用 subject
时没有得到异常的原因是它没有引发异常。由于您在 save_image
中设置了一个救援块,如果在其中抛出异常,将调用救援块并且不会将异常传播给调用者,而是 image_processing_error
被调用。
所以在您的规范中,当您调用 subject
时,您不会得到异常,而是会从 image_processing_error
中得到解析错误,据我了解,这实际上是预期行为。
在这种情况下,您可以做的是测试从 subject
获得的结果是否与您在这种情况下收到的预期错误消息匹配,例如:
it "returns the error messages" do
expect(response.body).to include("is invalid", "must be implemented")
end