欢迎光临Software MyZone,有问题可留言或到站点论坛发帖,争取第一时间帮忙解决 || 站点论坛:火龙论坛 || 淘宝小店:应小心的易淘屋 【欢迎大家提建设性意见】

rspec语法积累

Rspec代码  收藏代码
  1. 1 对象.should(_not) be_方法 :应该(不应该)怎么样,方法的返回值为true/false
  2. describe User do
  3.     it ”should be in any roles assigned to it” do
  4.         user = User.new
  5.         user.assign_role(“assigned role”)
  6.         user.should be_in_role(“assigned role”)
  7.     end
  8.     it ”should not be in any roles unassigned to it” do
  9.         user = User.new
  10.         user.assign_role(“assigned role”)
  11.         user.should_not be_in_role(“unassigned role”)
  12.     end
  13. end

 

Rspec代码  收藏代码
  1. 2 before/after(:each/:all) do end
  2. before(:all) do
  3.   # 会在所有example运行前被调用一次
  4.   end
  5.   before do
  6.   # 与before(:each)相同,会在每个example运行前被调用一次
  7.   end
  8.   after(:each) do
  9.   # 会在每个example运行完后被调用一次
  10.     @post.destroy unless @post.new_record?
  11.   end
  12.   after(:all) do
  13.     # 会在所有examples运行完之后被调用一次
  14.     Post.destroy_all
  15.   end
  16. 实例:
  17. describe Post do
  18.   before(:each) do
  19.     @post = Post.new(valid_post_hash) # grabs the hash below
  20.   end
  21.   it ”should be valid” do
  22.     @post.should be_valid
  23.   end
  24.   it ”should not be valid without a title” do
  25.     @post.title = ”
  26.     @post.should_not be_valid
  27.   end
  28.   it ”should not be valid without a body” do
  29.     @post.body = ”
  30.     @post.should_not be_valid
  31.   end
  32.   def valid_post_hash
  33.     {:title => ’test’, :body => ’test body’}
  34.   end
  35. end

 

Rspec代码  收藏代码
  1. 3 走验证should be_valid
  2. 实例:
  3. post.should be_valid
Rspec代码  收藏代码
  1. 4 基本语法
  2. Strings:
  3. ‘foo’.should == ’foo’
  4. ‘foo’.should === ’foo’
  5. ‘foo’.should_not equal(‘foo’)
  6. ”.should be_empty
  7. ‘foo with bar’.should include(‘with’)
  8. ‘http://fr.ivolo.us’.should match(/http:\/\/.+/i)
  9. nil.should be_nil
  10. Numbers:
  11. 100.should < 200
  12. 200.should >= 100
  13. (200 - 100).should == 100
  14. # (100 - 80) is less than 21
  15. 100.should be_close(80,21)
  16. Arrays:
  17. [1,2,3].should have(3).items
  18. [].should be_empty
  19. [1,2,3].should include(2)
  20. Hashes:
  21. {}.should be_empty
  22. {:post => {:title => ’test’}}.should have_key(:post)
  23. {:post => {:title => ’test’}}.should_not have_key(:title)
  24. false.should be_false
  25. true.should be_true
  26. Records:
  27. # assuming @post = Post.new(:title => ’test’)
  28. @post.should be_instance_of(Post)
  29. @post.should respond_to(:title)

 

Rspec代码  收藏代码
  1. 5 有关数据库的操作
  2. 实例:
  3. def comment
  4.   @post = Post.find(params[:id])
  5.   @comment = Comment.new(params[:comment])
  6.   respond_to do |format|
  7.     if @comment.save && @post.comments.concat(@comment)
  8.       flash[:notice] = ’Comment was successfully updated.’
  9.       format.html { redirect_to post_path(@blogger, @post) }
  10.       format.xml { head :o k }
  11.     else
  12.       flash[:notice] = ’Error saving comment.’
  13.       format.html { redirect_to post_path(@blogger, @post) }
  14.       format.xml { render :x ml => @comment.errors.to_xml }
  15.     end
  16.   end
  17. end
  18. 我需要确保我能够对帖子发布评论:
  19. it ”should add comments to the post” do
  20.   post = posts(:one)
  21.   comment_count = post.comments.size
  22.   post :comment, :id => 1, :comment => {:title => ’test’, :body => ’very nice!’}
  23.   post.reload
  24.   post.comments.size.should == comment_count + 1
  25.   flash[:notice].should match(/success/i)
  26.   response.should redirect_to(posts_path(@blogger, @post))
  27. end
  28. 看起来不错?但这个测试例实际测试了许多不该它来测试的东西,它应该只测试action,但是它却连同model也一并测试了,并且它还依赖于fixtures。
  29. 我们可以使用一个mock object来代替真是的post对象:
  30. post = mock_model(Post)
  31. 现在我们需要关注comment的第一行:
  32. @post = Post.find(params[:id])
  33. 我希望这一行在测试时得到执行,但是不用测试,我也知道这行代码肯定是工作正常的,因此,我现在要做的就是让这行代码返回我在上面创建的那个mock object:
  34. Post.should_receive(:find).and_return(post)
  35. 或者这样:
  36. Post.stub!(:find).and_return(post)
  37. 但 是请注意,should_receive和stub!虽然都可以让Post.find返回我的mock object,但是他们的区别却是巨大的,如果我调用了stub!,但是却没有调用Post.find,stub!不会抱怨什么,因为它是个老实人,但是 should_receive就不用,如果我告诉should_receive我会调用Post.find,但却没调用,那问题就来了,它会抱怨为何我不 守信用,并抛出一个异常来警告我。
  38. 但是跟在他们后面的and_return的作用却是完全相同的,它让你mock或者stub的方法返回你传递给它的任何参数。
  39. 接下来,我需要对comment做同样的事情:
  40. comment = mock_model(Comment)
  41. Comment.should_receive(:new).with({:title => ’comment title’, :body => ’comment body’}).and_return(comment)
  42. 接下来我需要关注这条语句:
  43. if @comment.save && @post.comments.concat(@comment)
  44. 同上面一样:
  45. comment.should_receive(:save).and_return(true)
  46. post.comments.should_receive(:concat).and_return(comment)
  47. 下面我需要测试flash及redirect:
  48. flash[:notice].should match(/success/i)
  49. response.should redirect_to(posts_path(blogger, post))
  50. 现在,还剩下最后一件事情:这个action必须使用blogger变量来进行重定向,这里我使用instance_variable_set来完成这个工作:
  51. blogger = mock_model(User)
  52. @controller.instance_variable_set(:@blogger, blogger)
  53. 基本就是这样,下面是将部分代码放入before中的完整代码:
  54. describe PostsController, ”comment”, :behaviour_type => :controller, do
  55.   before do
  56.     @post = mock_model(Post)
  57.     Post.should_receive(:find).and_return(@post)
  58.     @comment = mock_model(Comment)
  59.     Comment.should_receive(:new).with.({:title => ’comment title’, :body => ’comment body’}).and_return(@comment)
  60.     @blogger = mock_model(User)
  61.     @controller.instance_variable_set(:@blogger, @blogger)
  62.   end
  63.   it ”should add comments to the post” do
  64.     @comment.should_receive(:save).and_return(true)
  65.     @post.comments.should_receive(:concat).and_return(@comment)
  66.     post :comment, :id => @post.id, :comment => {:title => ’comment title’, :body => ’comment body’}
  67.     flash[:notice].should match(/success/i)
  68.     response.should redirect_to(posts_path(@blogger, @post))
  69.   end
  70. end

详细参考:http://firedragonpzy.iteye.com/blog/1471589

发表评论