[英]How to test destroy failure in controller using Rspec?
I have a books controller with the following action...我有一个具有以下操作的书籍控制器...
def destroy
@book = Book.find(params[:id])
if @book.destroy
redirect_to(books_path)
else
render('delete')
end
end
I am able to test the the first if case, but not the situation where @book.destroy returns false.我可以测试第一个 if 情况,但不能测试 @book.destroy 返回 false 的情况。 My question is - how do I make @book.destroy fail?
我的问题是 - 如何让 @book.destroy 失败? I want to write a rspec test to cover that case.
我想编写一个 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
I tried writing the above thinking that allow(@book).to receive(:destroy).and_return(true) would make destroy() return false, but instead, it still returns true and tests the code in the first if statement.我试着写上面的想法,allow(@book).to receive(:destroy).and_return(true) 会使 destroy() 返回 false,但相反,它仍然返回 true 并测试第一个 if 语句中的代码。 I have no idea how to cover the code in the else statement.
我不知道如何覆盖 else 语句中的代码。 Any help please?
请问有什么帮助吗?
Thanks.谢谢。
The main reason your test does not work is that Book.find
will load the record from the database and create a new instance of the class which means that #destroy
is not being called on the same object that you have stubbed.您的测试不起作用的主要原因是
Book.find
将从数据库加载记录并创建该类的新实例,这意味着不会在您存根的同一对象上调用#destroy
。
You need to stub the Book.find
method so that it returns the book instance with the stubbed method:您需要存根
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.