Rails + Rspec:如何存根记录以使其标记为无效?



我有一个Purchase模型,方法:

def set_status_to_in_progress!
  self.update_attributes!(status: IN_PROGRESS)
end

和一个失败的rspec测试:

context "self is invalid" do
  it "raises an error" do
    purchase = Purchase.new
    purchase.stub(:valid?).and_return(:false)
    expect { purchase.set_status_to_in_progress! }.to raise_error
  end
end

返回

Failures:
      1) Purchase#set_status_to_in_progress! self is invalid raises an error
         Failure/Error: expect { purchase.set_status_to_in_progress! }.to raise_error
           expected Exception but nothing was raised
         # ./spec/models/purchase_spec.rb:149:in `block (4 levels) in <top (required)>'

我认为存根valid?将足以使ActiveRecord update_attributes!方法引发错误?我怎么让它上升?

尝试将:false改为false

purchase.stub(:valid?).and_return(false)

purchase.should_receive(:valid?).and_return(false)

否则你可以存根任何Purchase的实例

Purchase.any_instance.should_receive(:valid?).and_return(false)

这是权威的指南,当无法在模型上模拟真实验证时,可以成功测试验证错误。在我的例子中,SupportRequest模型没有任何验证,但我想测试,就像有一个一样,所以我首先做的是创建一个double,然后使它在尝试更新时返回false,然后向记录添加错误,最后测试记录在那里。:)

describe "with invalid data" do
  before do
    the_double = instance_double("SupportRequest", id: support_request.id)
    active_model_errors = ActiveModel::Errors.new(the_double).tap { |e| e.add(:description, "can't be blank") }
    allow_any_instance_of(SupportRequest).to receive(:update_attributes).and_return(false)
    allow_any_instance_of(SupportRequest).to receive(:errors).and_return(active_model_errors)
    put "/api/support_requests/#{support_request.id}",
      params: {
        data: {
          type: "support-requests",
          attributes: {}
        }
      },
      headers: authenticated_header(support_agent)
  end
  it "should not create a new support_request" do
    expect_json(errors: [
      {
        source: {
          pointer: "/data/attributes/description"
        },
        detail: "can't be blank"
      }
    ])
  end
  it "should return status code (422)" do
    expect_status(422)
  end
end

最新更新