首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

rspec语法累积

2012-09-24 
rspec语法积累1 对象.should(_not) be_方法 :应该(不应该)怎么样,方法的返回值为true/falsedescribe User

rspec语法积累

1 对象.should(_not) be_方法 :应该(不应该)怎么样,方法的返回值为true/falsedescribe User doit "should be in any roles assigned to it" do     user = User.newuser.assign_role("assigned role")user.should be_in_role("assigned role")endit "should not be in any roles unassigned to it" do     user = User.newuser.assign_role("assigned role")user.should_not be_in_role("unassigned role")endend

2 before/after(:each/:all) do end before(:all) do  # 会在所有example运行前被调用一次  end  before do  # 与before(:each)相同,会在每个example运行前被调用一次  end  after(:each) do  # 会在每个example运行完后被调用一次    @post.destroy unless @post.new_record?  end  after(:all) do    # 会在所有examples运行完之后被调用一次    Post.destroy_all  end实例:describe Post do  before(:each) do    @post = Post.new(valid_post_hash) # grabs the hash below  end  it "should be valid" do    @post.should be_valid  end  it "should not be valid without a title" do    @post.title = ''    @post.should_not be_valid  end  it "should not be valid without a body" do    @post.body = ''    @post.should_not be_valid  end  def valid_post_hash    {:title => 'test', :body => 'test body'}  endend

3 走验证should be_valid实例:post.should be_valid


4 基本语法Strings:'foo'.should == 'foo''foo'.should === 'foo''foo'.should_not equal('foo')''.should be_empty'foo with bar'.should include('with')'http://fr.ivolo.us'.should match(/http:\/\/.+/i)nil.should be_nilNumbers:100.should < 200200.should >= 100(200 - 100).should == 100# (100 - 80) is less than 21100.should be_close(80,21)Arrays:[1,2,3].should have(3).items[].should be_empty[1,2,3].should include(2)Hashes:{}.should be_empty{:post => {:title => 'test'}}.should have_key(:post){:post => {:title => 'test'}}.should_not have_key(:title)false.should be_falsetrue.should be_trueRecords:# assuming @post = Post.new(:title => 'test')@post.should be_instance_of(Post)@post.should respond_to(:title)

5 有关数据库的操作实例:def comment  @post = Post.find(params[:id])  @comment = Comment.new(params[:comment])  respond_to do |format|    if @comment.save && @post.comments.concat(@comment)      flash[:notice] = 'Comment was successfully updated.'      format.html { redirect_to post_path(@blogger, @post) }      format.xml { head :o k }    else      flash[:notice] = 'Error saving comment.'      format.html { redirect_to post_path(@blogger, @post) }      format.xml { render :x ml => @comment.errors.to_xml }    end  endend我需要确保我能够对帖子发布评论:it "should add comments to the post" do  post = posts(:one)  comment_count = post.comments.size  post :comment, :id => 1, :comment => {:title => 'test', :body => 'very nice!'}  post.reload  post.comments.size.should == comment_count + 1  flash[:notice].should match(/success/i)  response.should redirect_to(posts_path(@blogger, @post))end看起来不错?但这个测试例实际测试了许多不该它来测试的东西,它应该只测试action,但是它却连同model也一并测试了,并且它还依赖于fixtures。我们可以使用一个mock object来代替真是的post对象:post = mock_model(Post)现在我们需要关注comment的第一行:@post = Post.find(params[:id])我希望这一行在测试时得到执行,但是不用测试,我也知道这行代码肯定是工作正常的,因此,我现在要做的就是让这行代码返回我在上面创建的那个mock object:Post.should_receive(:find).and_return(post)或者这样:Post.stub!(:find).and_return(post)但 是请注意,should_receive和stub!虽然都可以让Post.find返回我的mock object,但是他们的区别却是巨大的,如果我调用了stub!,但是却没有调用Post.find,stub!不会抱怨什么,因为它是个老实人,但是 should_receive就不用,如果我告诉should_receive我会调用Post.find,但却没调用,那问题就来了,它会抱怨为何我不 守信用,并抛出一个异常来警告我。但是跟在他们后面的and_return的作用却是完全相同的,它让你mock或者stub的方法返回你传递给它的任何参数。接下来,我需要对comment做同样的事情:comment = mock_model(Comment)Comment.should_receive(:new).with({:title => 'comment title', :body => 'comment body'}).and_return(comment)接下来我需要关注这条语句:if @comment.save && @post.comments.concat(@comment)同上面一样:comment.should_receive(:save).and_return(true)post.comments.should_receive(:concat).and_return(comment)下面我需要测试flash及redirect:flash[:notice].should match(/success/i)response.should redirect_to(posts_path(blogger, post))现在,还剩下最后一件事情:这个action必须使用blogger变量来进行重定向,这里我使用instance_variable_set来完成这个工作:blogger = mock_model(User)@controller.instance_variable_set(:@blogger, blogger)基本就是这样,下面是将部分代码放入before中的完整代码:describe PostsController, "comment", :behaviour_type => :controller, do  before do    @post = mock_model(Post)    Post.should_receive(:find).and_return(@post)    @comment = mock_model(Comment)    Comment.should_receive(:new).with.({:title => 'comment title', :body => 'comment body'}).and_return(@comment)    @blogger = mock_model(User)    @controller.instance_variable_set(:@blogger, @blogger)  end  it "should add comments to the post" do    @comment.should_receive(:save).and_return(true)    @post.comments.should_receive(:concat).and_return(@comment)    post :comment, :id => @post.id, :comment => {:title => 'comment title', :body => 'comment body'}    flash[:notice].should match(/success/i)    response.should redirect_to(posts_path(@blogger, @post))  endend

热点排行