RSpec进阶指南(1): rspec_scaffold

不同于前面那篇入门性的指南(如果还没读过,建议先阅读那篇文章然后再回来),这一系列将涵盖RSpec在Rails中的使用以及一些高级主题,来自我的同事Josh Stephenson,这是第一篇。

要使用RSpec来测试你的Rails应用,有一个比较简单的方法,使用rspec_scaffold生成器来代替scaffold_resource(Rails2.0中已更名为scaffold)。

$ ./script/generate rspec_scaffold post title:string body:text author:integer created_at:datetime updated_at:datetime
     exists app/models/
     exists app/controllers/
     exists app/helpers/
     create app/views/posts
     create spec/controllers/
     create spec/models/
     create spec/helpers/
     create spec/fixtures/
     create spec/views/posts
     create spec/controllers/posts_controller_spec.rb
     create app/controllers/posts_controller.rb
     create spec/helpers/posts_helper_spec.rb
     create app/helpers/posts_helper.rb
     create app/views/posts/index.rhtml
     create app/views/posts/show.rhtml
     create app/views/posts/new.rhtml
     create app/views/posts/edit.rhtml
     create app/models/post.rb
     create spec/fixtures/posts.yml
     create spec/models/post_spec.rb
     create spec/views/posts/edit.rhtml_spec.rb
     create spec/views/posts/index.rhtml_spec.rb
     create spec/views/posts/new.rhtml_spec.rb
     create spec/views/posts/show.rhtml_spec.rb
     create db/migrate
     create db/migrate/001_create_posts.rb
     route map.resources :posts

就像你看到的,rspec_scaffold会为你生成model,controller,helper,views以及其它一些辅助的spec文件。让我们先来看看spec/models/post_spec.rb吧:

# this is called a context (or a describe block)
require File.dirname(__FILE__) + '/../spec_helper'
describe Post do
  before(:each) do
    @post = Post.new
  end
  # this is called an example:
  it "should be valid" do
    @post.should be_valid
  end
end

首先,我们需要注意,所有的specs都拥有behaviour_type属性,spec使用它来确定需要加载哪些spec helpers,我们可以通过下面的语句来指定它:

describe Post, "a useful comment", :behaviour_type => :model do

这将会加载测试model所需的helpers,让我们继续回到post_spec.rb,这段代码其实没有任何意义,因为post model什么也没有做,所以让我们先来给post model加一些validations:

class Post < ActiveRecord::Base
  validates_presence_of :title
  validates_presence_of :body
  validates_uniqueness_of :title
end

一些人可能认为测试validations没什么用,因为几乎可以肯定它们肯定是工作正常的,但是作为应用的最底层代码,我还是愿意对它们的行为进行检查,以确保它们符合我的预期:

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

尽管RSpec的可读性并不是很好,但我认为至少上面这段代码写的相当清楚,应该不需要再进行解释,不过对于几个比较特殊的方法还是要说明一下:

  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

This entry was posted in 测试. Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.
  • ahtest

    谢谢你的贡献,受用…

无觅相关文章插件,快速提升流量