[英]How to write an RSpec test for a simple PUT update?
I'm trying to solidify my understanding of rails and the BDD workflow, so I wanted to start small by creating one of those mini-blogs, but with rspec. 我正在努力巩固我对rails和BDD工作流程的理解,所以我想通过创建其中一个迷你博客来开始,但是使用rspec。 Right now I have an ArticlesController and Article model, and associated rspec files.
现在我有一个ArticlesController和Article模型,以及相关的rspec文件。 Article is very simple, has just title:string and content:text, and the ArticlesController is RESTful - although I hand wrote the MCV for Article, it's basically the same as if I used a scaffold to create it.
文章非常简单,只有标题:字符串和内容:文本,而ArticlesController是RESTful - 虽然我手写了MCV for Article,但它基本上和我用脚手架创建它一样。
However I don't really know what I'm doing when it comes to writing a test in rspec for the PUT update. 但是,当我在rspec中为PUT更新编写测试时,我真的不知道我在做什么。 I'm using Factory Girl to create the article object, and so far my code looks like:
我正在使用Factory Girl来创建文章对象,到目前为止我的代码看起来像:
#factories.rb
FactoryGirl.define do
factory :article do
title "a title"
content "hello world"
end
#articles_controller_spec.rb
before(:each) do
@article = Factory(:article)
end
describe "PUT 'update/:id'" do
it "allows an article to be updated" do
@attr = { :title => "new title", :content => "new content" }
put :update, :id => @article.id, :article => @attr
response.should be_successful
end
end
However I keep getting: 但是我一直在:
Failures:
1) ArticlesController PUT 'update/:id' allows an article to be updated
Failure/Error: response.should be_successful
expected successful? to return true, got false
What am I doing wrong? 我究竟做错了什么? And am I using the right tools?
我使用正确的工具吗? When I run my test server, New, Edit, Destroy all work as I would expect them to, so I'm guessing this is a problem with my understanding of RSpec.
当我运行我的测试服务器时,New,Edit,Destroy所有工作正如我所期望的那样,所以我猜这是我对RSpec理解的问题。 Let me know if I'm wrong - thanks!
如果我错了,请告诉我 - 谢谢!
You forgot to .reload
your @article
, and on update
action your response most likely perform redirect, so 你忘记了
.reload
你的@article
,在update
操作上,你的回复最有可能执行重定向,所以
RSpec 2: RSpec 2:
describe "PUT update/:id" do
let(:attr) do
{ :title => 'new title', :content => 'new content' }
end
before(:each) do
put :update, :id => @article.id, :article => attr
@article.reload
end
it { response.should redirect_to(@article) }
it { @article.title.should eql attr[:title] }
it { @article.content.should eql attr[:content] }
end
Rspec 3: Rspec 3:
describe "PUT update/:id" do
let(:attr) do
{ :title => 'new title', :content => 'new content' }
end
before(:each) do
put :update, :id => @article.id, :article => attr
@article.reload
end
it { expect(response).to redirect_to(@article) }
it { expect(@article.title).to eql attr[:title] }
it { expect(@article.content).to eql attr[:content] }
end
When you are doing a PUT :update
remember that you are editing an existing model, which you need to call in the put
. 当你正在做一个
PUT :update
记住,你是编辑现有的模式,你需要在调用put
。 Just pass your @article
and update the attributes as follows. 只需传递您的
@article
并更新属性,如下所示。
describe "PUT 'update/:id'" do
it "allows an article to be updated" do
put :update, :id => @article.id, :article => @article.attributes = { :title => "new title", :content => "new content" }
response.should be_successful
end
end
FactoryGirl.define :article do
title "a title"
content "hello world"
end
before(:each) do
@article = Factory(:article)
end
it "should re-render edit template on failed update" do
@attr = { :title => "", :content => "new content" }
put :update, :id => @article.id, :article => @attr
flash[:notice].should be_nil
response.should render_template('edit')
end
it "should redirect to index with a notice on successful update" do
@attr = { :title => "new title", :content => "new content" }
put :update, :id => @article.id, :article => @attr
assigns[:article].should_not be_new_record
flash[:notice].should_not be_nil
response.should redirect_to(:action => 'index')
end
The way I like to test the update method is to just ensure that the updated_at time is greater than it was before. 我喜欢测试更新方法的方法是确保updated_at时间比以前更大。 When you do this you can change the contents of the entire instance variable and still check if everything was updated.
执行此操作时,您可以更改整个实例变量的内容,并仍然检查是否所有内容都已更新。 For instance:
例如:
describe "PUT 'update/:id'" do
it "allows an article to be updated" do
prev_updated_at = @article.updated_at
@attr = { :title => "new title", :content => "new content" }
put :update, :id => @article.id, :article => @attr
@article.reload
@article.updated_at.should != prev_updated_at
end
end
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.