`
fireDragonpzy
  • 浏览: 460848 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

rspec语法积累

阅读更多
1 对象.should(_not) be_方法 :应该(不应该)怎么样,方法的返回值为true/false
describe User do
	it "should be in any roles assigned to it" do 
	    user = User.new
		user.assign_role("assigned role")
		user.should be_in_role("assigned role")
	end

	it "should not be in any roles unassigned to it" do 
	    user = User.new
		user.assign_role("assigned role")
		user.should_not be_in_role("unassigned role")
	end

end

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'}
  end
end


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_nil

Numbers:

100.should < 200
200.should >= 100
(200 - 100).should == 100

# (100 - 80) is less than 21
100.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_false
true.should be_true

Records:

# 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
  end
end
我需要确保我能够对帖子发布评论:

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))
  end
end
分享到:
评论

相关推荐

    Ruby语言中文教程

    实践中,你可以尝试解决实际问题,例如构建小型应用,或者参与开源项目,这样既能加深理解,又能积累实战经验。记住,学习编程最重要的是动手实践,通过不断的试错和调试,你会对Ruby有更深入的认识。

    RubymotionDemo:恰恰网络积累的各种App开发过程中的常用Demo Thanks @smartweb

    这个“RubymotionDemo”项目显然集合了恰恰网络在App开发过程中积累的各种常用示例和代码片段,对于学习和理解RubyMotion的开发流程具有很高的参考价值。下面将详细探讨RubyMotion及其相关知识点。 1. **RubyMotion...

    ruby重构中文+英文

    - **简洁语法**:Ruby的简洁语法使得代码更容易阅读和理解,有助于重构工作的进行。 #### 六、常见的Ruby重构技巧 - **提取方法**:将重复的代码提取成独立的方法。 - **替换算法**:当发现更高效的算法时,可以...

    Ruby-Tracks是一个采用RubyonRails构建的GTDWeb应用程序

    1. **Ruby编程基础**:了解Ruby的基本语法、类、模块、方法和数据结构,以及面向对象编程的概念。 2. **Rails框架**:理解Rails的路由、控制器、模型、视图以及ActiveRecord(ORM)的工作原理。 3. **MVC架构**:...

    Ruby语言中文教程.rar

    Ruby是一种面向对象的、动态类型的编程语言,以其简洁、优雅的语法著称。这本"Ruby语言中文教程"是为初学者和有一定编程基础的人设计的,旨在帮助他们快速掌握Ruby的基本概念和核心特性。 首先,Ruby的核心理念是...

    ruby_rails_courses

    Ruby on Rails,简称Rails,是基于Ruby编程语言的一个开源Web应用程序框架,它遵循MVC(模型-视图-控制器)架构模式,旨在提高...随着经验的积累,你还可以探索更高级的主题,如并发处理、缓存策略、复杂的数据分析等。

    ajit-notebook:阿吉特的笔记本

    这个“笔记本”可能是为了分享知识、记录编程经验或者是个人学习过程中的积累。 【描述】"ajit-notebook:阿吉特的笔记本"的描述非常简洁,没有提供额外的信息。但我们可以推测,这个项目的核心内容是关于Ruby语言的...

    学习

    6. **调试和测试**:学习如何使用Ruby的调试工具,如byebug,以及测试驱动开发(TDD)和行为驱动开发(BDD)的概念,例如RSpec和Minitest。 7. **社区参与**:加入Ruby社区,如Stack Overflow、GitHub和Ruby China等,...

    concierge:car2go帮手服务

    Ruby是一种面向对象的脚本语言,以其简洁、优雅的语法和强大的元编程能力而闻名。在这个项目中,Ruby被用来构建一个交互式的后端系统,能够与car2go的API进行无缝对接,处理用户的预定请求,获取车辆信息,以及管理...

    aA_Classwork

    在这个资料库中,我们可以期待找到一系列与Ruby相关的代码练习、项目示例以及可能的学习笔记,这些都是学员在学习过程中积累的实践经验。 Ruby是一种面向对象的、简洁且可读性强的编程语言,特别适合初学者入门。在...

    Ruby on Rails打造企业级RESTful API项目实战我的云音乐

    2. **Ruby基础知识**:理解并掌握Ruby语言的基本语法、数据类型、控制结构、类与对象等核心概念,是运用Rails的基础。Ruby是一种动态、面向对象的语言,它的简洁性和表达力使得代码更易于阅读和编写。 3. **Rails...

    randomprojects:这将是我成为一名自学成才的程序员过程中所做的随机项目的存储库

    在IT行业中,编程和软件开发是一项复杂而富有挑战性的任务,尤其对于自学成才的程序员来说,积累实践经验是提升技能的关键。"randomprojects"这个存储库恰好为学习者提供了一个平台,来实践和展示他们在编程旅程中的...

    Ruby-on-Rails-Practice

    1. **Ruby语言基础**:Ruby是一种面向对象的、动态类型的编程语言,它的语法简洁易读,支持元编程,使得代码更加灵活。理解Ruby的基本数据类型(如字符串、数字、数组、哈希)、控制流(if、case、循环)、类和对象...

    Learning

    标题“Learning”暗示了这是一个关于学习和知识积累的项目,特别是与编程相关的学习。描述指出这是一个个人的“学习空间”,用于存储在其他网站上学习时创建的源代码,表明这可能是一个GitHub仓库或者类似的版本控制...

Global site tag (gtag.js) - Google Analytics