繁体   English   中英

如何使用 Rspec 测试控制器中的销毁故障?

[英]How to test destroy failure in controller using Rspec?

我有一个具有以下操作的书籍控制器...

def destroy
   @book = Book.find(params[:id])
   if @book.destroy
     redirect_to(books_path)
   else
     render('delete')
   end
 end

我可以测试第一个 if 情况,但不能测试 @book.destroy 返回 false 的情况。 我的问题是 - 如何让 @book.destroy 失败? 我想编写一个 rspec 测试来涵盖这种情况。

describe "destroy" do
   before(:context) do
     @book = create(:book)
   end
   context "failing the destroy function" do
     it "renders delete" do
       allow(@book).to receive(:destroy).and_return(false)
       delete :destroy, params: { id: @book.id }
       expect(response).to render_template(:delete)
     end
   end
 end

我试着写上面的想法,allow(@book).to receive(:destroy).and_return(true) 会使 destroy() 返回 false,但相反,它仍然返回 true 并测试第一个 if 语句中的代码。 我不知道如何覆盖 else 语句中的代码。 请问有什么帮助吗?

谢谢。

您的测试不起作用的主要原因是Book.find将从数据库加载记录并创建该类的新实例,这意味着不会在您存根的同一对象上调用#destroy

您需要存根Book.find方法,以便它使用存根方法返回 book 实例:

describe "destroy" do
  context "failing the destroy function" do
    let(:book) { build_stubbed(:book) } # use let instead of ivars

    # don't use before :context unless you actually 
    # have a real reason. You should strive to have 
    # each example setup/teardown on their own 
    before do
      allow(book).to receive(:destroy).and_return(false)
      allow(Book).to receive(:find).and_return(book)
    end 

    it "renders delete" do
      delete :destroy, params: { id: book.id }
      expect(response).to render_template(:delete)
    end
  end
end

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM