Everyday Rails RSpec

June 19, 2014

前段时间利用零碎时间走马观花的把The RSpec Book的前面部分(part1~part4)过了一遍
发现自己在测试这方面缺口真是不小
The RSpec Book前半部分偏理论性的东西很多, 啃得很生硬
于是买了本Andor Chen译的<使用 RSpec 测试 Rails 程序>以作实践

RSpec

RSpec 2.99之后版本, 需要稍作变动 在Gemfile里加上gem 'rspec-collection_matchers'

对于 expectation , 之前的版本惯用的should形式
被改写为expect(<obj>).to <matcher>这种用法

subject()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
describe CheckingAccount, "with $50" do
  subject { CheckingAccount.new(Money.new(50, :USD)) }
  it { is_expected.to have_a_balance_of(Money.new(50, :USD)) }
  it { is_expected.not_to be_overdrawn }
end

describe CheckingAccount, "with a non-zero starting balance" do
  subject(:account) { CheckingAccount.new(Money.new(50, :USD)) }
  it { is_expected.not_to be_overdrawn }
  it "has a balance equal to the starting balance" do
    #account.balance.should eq(Money.new(50, :USD))
    expect(:account).to eq(Money.new(50, :USD))
  end
end

mock & stub

RSpec 2.14之前的语法要这么写

1
2
3
d = double(:message1 => true)
d.stub(:message2).and_return(:value)
real_object.stub(:message).and_return(:value)

之后可以这么写

1
2
3
d = double(:message1 => true)
allow(d).to receive(:message2).and_return(:value)
allow(real_object).to receive(:message).and_return(:value)

FactoryGirl

简化factory_girl代码

加到rails_helper.rb
1
config.include FactoryGirl::Syntax::Methods

Aliases

可以用aliases简化关联关系

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
FactoryGirl.define do

  factory :user, aliases: [:author, :commenter] do
    first_name "John"
    last_name "Deo"
  end

  factory :post do
    author  #用以替代 association :author, factory: :user
  end

  factory :comment do
    commerter  #替代  association :commenter, factory: :user
  end

end

Associations

如果association的名字与factory的名字相同, 可以省略association
也可以指定不同名的factory并覆盖某属性

1
2
factory :post do
  author factory: :user, last_name: "skywalker"

Capybara

以下方法别名只可用在功能测试中

given对应let
background对应before
feature对应describe
scenario对应it

涉及javascript

1
2
3
feature "About BigCo modal" do
  scenario "toggles display of the modal about display", js: true do
    # blablalbla

另外如果开启了js: true时, 要测试DB变化, 有可能DB反映慢导致测试失败, 可以采取下面办法:

1
2
3
4
5
6
expect {
  fill_in_new_user_data("new_user@example.com")
  check "user_admin"
  click_button "Create User"
  sleep 1
}.to change(User, :count).by(1)

Launchy

save_and_open_page

Guard

bundle exec guard init rspec

在ActiveAdmin下自定义filter

rails4之后,之前的`model`里加入`search_methods :filter_name`的做法已经失效,需修改为:``` ruby class PromoCode (ids) { with_tags(ids) } def self. …… Continue reading

Mac上搭建Phonegap环境

Published on October 02, 2014

Rails遗留程序里最常犯的错误(译)

Published on July 23, 2014