Rspec: everyday-rspec实操。

git checkout -b my-02-setup origin/01-untested

解释:从已经克隆后的远程,下载分支到本地。 

Branch my-02-setup set up to track remote branch 01-untested from origin.
Switched to a new branch 'my-02-setup'

第二章 开始 

1. 

Gemfile group :development, :test do

  gem 'rspec-rails', '~> 3.6.0' # 省略了 Rails 提供的其他 gem

end

2. 测试数据库。

3. 配置RSpec:

$ bin/rails generate rspec:install

打开.rspec文件,增加:

--format documentati on   #文档阅读模式,在测试时显示要测试的文本,并标记是否成功。
--warnings   #添加警告标志,在真实应用中有用。

作者强烈建议看spec/spec_helper.rb和spec/rails_helper.rb的设置,理解各项设置的作用。

3.1 使用 rspec binstub 提升测试组件的启动速度

Gemfile

group :development do

# 这一分组中的其他 gem ...

gem 'spring-commands-rspec'

end

然后 bundle exec spring binstub rspec, 如果不想用这个,直接bundle exec rspec.

然后bin/rspec试一试。

4 controller(可选)

可以使用 rspec-rails 提供的默认设置;不过这样会生成额外的样板代码,你可以自己动手删 除,也可以放着不管。

打开 config/application.rb 文件,在 Application 类中加入下面的代码:

module Projects
  class Application < Rails::Application
    config.load_defaults 5.1
    config.generators do |g|
      g.test_framework :rspec,
        fixtures: false  #暂时不要固件
        view_specs: false #不要视图测试,UI相关的测试交给集成测试。
        helper_specs: false #生成控制器时,不生成对应的辅助方法测试文件
        routing_specs: false #是不生成针对 config/routes.rb 的测试文件。
        #如果是大型应用,路由很复杂,最好还是测试一下
    end
  end
end

5,附加:(Rails指南有一整章节。)

如果经常新建Rails, 可以创建一个Rails 应用模板,自动把 RSpec 和相关的配置添加到应用 的 Gemfile 和配置文件中,而且还可以自动创建测试数据库。Daniel Kehoe 开发的 Rails Composer 是个 不错的工具。


第 3 章 模型测

 git checkout -b my-03-models origin/02-setup

 复制前一章分支,增加了user, project, note, task.4个models. 添加了5个gem。

 

1.2编写模型测试。

bin/rails g rspec:model user

模型测试应该包含:

• 使用有效属性实例化的模型应该是有效的;

• 无法通过数据验证的数据,测试应该失败;

• 类方法和实例方法应按预期可正常使用。


2.2编写模型测试 

bin/rspec

首先,确定要验证的example。模型验证User

RSpec.describe User, type: :model do
  it "is valid with a first name, last name, email, and password"
  it "is invalid without a first name"
  it "is invalid without a last name"
  it "is invalid without an email address"
  it "is invalid with a duplicate email address"
  it "returns a user's full name as a string"
  # pending "add some examples to (or delete) #{__FILE__}"
end

pending在之后章节学习。

2.3 RSpec句法:新:expect().to eq()

  it "is valid with a first name, last name, email, and password" do
    user = User.new(
      first_name: "Aaron",
...
    )
    expect(user).to be_valid   #be_valid也是匹配器。
  end

 然后bin/rspec,通过验证。

2.4 测试数据验证

include匹配器检验一个可以枚举的value中是否包括指定的值。  to_not和to匹配器。

  it "is invalid without a first name" do
    user = User.new(first_name: nil)
    user.valid?  #Rails语法,看是否新建的实例通过全部验证validations
    expect(user.errors[:first_name]).to include("can't be blank")
  end

然后bin/rspec通过验证。

另外,可以修改应用代码,看看对测试有什么影响。如果测试代码的输出没有变化,可能是测试没有与代码对接上,或者代码的行为与预期不同。 

关联模型的数据验证: 

bin/rails g rspec:model project   

这会生成models/project_spec.rb文件。也可以手动添加,但通过控制器添加文件,能防止打错字。 

加2个example. 

it "does not allow duplicate project names per user"

it "allows two users to share a project name" 

因为在app/models/project.rb中,增加了作用域验证,这里每个project的name只有一个用户,name不是唯一的但它对应的user_id,在Project中是唯一的。

validates :name, presence: true, uniqueness: { scope: :user_id }

我们应当养成数据验证的习惯,通过和不通过都要验证。 

比如:把验证代码临时注释掉,或者把测试的预期改成其他值,看看测试结果是否失败? 


3.5 测试实例方法

在User model中编写一个实例方法name。可以在测试文件user_spec.rb中使用,例子:

expect(user.name).to eq("Dave Bot") 

3.6测试类方法和作用域

在Note model中编写一个类方法search,它是一个作用域 

  scope :search, ->(term) {
    where("LOWER(message) LIKE ?", "%#{term.downcase}%")
  }
  #A scope是狭义的data 查询。用于检索和查询类的实例对象
  #scope()是类方法: scope(name, body, &body)

等同于:

  def self.search(term)
    where("LOWER(message) LIKE ?", "%#{term.downcase}%")
  end


  #返回的是一个相关的记录数据集合对象,ActiveRecord::Relation,类似Array
  #箭头函数是lambda表达式,->(){return},这里成为块参数。


  #where("LOWER(message) LIKE ?", "%#{term.downcase}%"), 不是很理解。
WHERE .. LIKE.. 模糊对比:SELECT * FROM events WHERE name LIKE '%Ruby%';

这里where()是rails语法糖。返回一个relation对象。

具体看query guide. 或者自己的博客activerecord:query

猜你喜欢

转载自www.cnblogs.com/chentianwei/p/9047596.html