Component | version |
---|---|
RubyMine | 5.0(Windows) |
Rails | 3.2.12 |
Rspec | 2.13.0 |
FactoryGirl | 4.2.0 |
Faker | 1.1.2 |
DatabaseCleaner | 0.9.1 |
Setup
- コードを書く
Gemfile
group :development, :test do
gem "rspec-rails"
gem "factory_girl_rails"
end
group :test do
gem "faker"
gem "capybara"
gem "database_cleaner"
end
-
bundle install
-
Tools > Run Rails Script > "rails", "generate rspec:install"
-
Tools > Run Rails Generator > model > Contact firstname:string lastname:string email:string phone:references
-
Tools > Run Rails Generator > model > Phone contact:references phone_type:string phone:string
-
Tools > Run Rake Task > db:migrate
1st red
- テストを書く
spec/models/contact_spec.rb
require 'spec_helper'
describe Contact do
it "is valid with a firstname and lastname"
it "is invalid without a firstname"
it "is invalid without a lastname"
it "is invalid with a duplicate email address"
end
- Run > Run > spec
pending
-
Toggle auto-test
-
テストを書く
spec/models/contact_spec.rb
require 'spec_helper'
describe Contact do
it "is valid with a firstname and lastname" do
contact = Contact.new(
firstname: 'Tatsuro',
lastname: 'Ueda',
email: 'weed_7777@yahoo.co.jp'
)
expect(contact).to be_valid
end
it "is invalid without a firstname" do
expect(Contact.new(firstname: nil).to have(1).errors_on(:firstname))
end
it "is invalid without a lastname" do
expect(Contact.new(lastname: nil).to have(1).errors_on(:lastname))
end
it "is invalid with a duplicate email address" do
Contact.create(
firstname: 'Tatsuro', lastname: 'Ueda', email: 'weed_7777@yahoo.co.jp'
)
contact = Contact.new(
firstname: 'hoge', lastname: 'fuga', email: 'weed_7777@yahoo.co.jp'
)
expect(contact).to have(1).errors_on(:email)
end
end
-
保存すると自動でテストが走り、こける
-
コードを書く
app/models/contact.rb
validates :firstname, presence: true
validates :lastname, presence: true
validates :email, presence: true, uniqueness: true
- 保存すると自動でテストが走り、合格する
2nd red
- テストを書く
spec/models/phone_spec.rb
describe Phone do
it "does not allow duplicate phone numbers per contact"
it "allows two contacts to share a phone number"
end
-
保存すると自動でテストが走り、pendingになる
-
テストを書く
spec/models/phone_spec.rb
describe Phone do
it "does not allow duplicate phone numbers per contact" do
contact = Contact.create(
firstname: 'Tatsuro', lastname: 'Ueda', email: 'weed_7777@yahoo.co.jp'
)
home_phone = contact.phones.create(
phone_type: 'home',
phone: '01-2345-6789'
)
mobile_phone = contact.phones.create(
phone_type: 'mobile',
phone: '01-2345-6789'
)
expect(mobile_phone).to_not be_valid
end
it "allows two contacts to share a phone number" do
contact = Contact.create(
firstname: 'Tatsuro', lastname: 'Ueda', email: 'weed_7777@yahoo.co.jp'
)
contact.phones.create(
phone_type: 'home',
phone: '01-2345-6789'
)
other_contact = Contact.new
other_phone = other_contact.phones.build(
phone_type: 'home',
phone: '01-2345-6789'
)
expect(other_phone).to be_valid
end
end
-
保存すると自動でテストが走り、こける
-
コードを書く
app/models/contact.rb
# belongs_to :phone
has_many :phones
app/models/phone.rb
attr_accessible :phone, :phone_type
validates :phone, uniqueness: { scope: :contact_id }
- 保存すると自動でテストが走り、合格する
3rd red
- テストを書く
spec/models/contact_spec.rb
describe "#name" do
it "returns a contact's full name as a string" do
contact = Contact.new(
firstname: "Tatsuro", lastname: "Ueda", email: "weed_7777@yahoo.co.jp"
)
expect(contact.name).to eq 'Tatsuro Ueda'
end
end
- Run > Run > spec
テストが走り、失敗する
-
Toggle auto-test
-
コードを書く
app/models/contact.rb
def name
[firstname, lastname].join " "
end
- 自動的にテストが走り、合格する
4th red
- テストを書く
spec/models/contact_spec.rb
describe "#by_letter" do
it "returns a sorted array of results that match" do
smith = Contact.create(
firstname: 'John', lastname: 'Smith', email: 'jsmith@example.com'
)
jones = Contact.create(
firstname: 'Tim', lastname: 'Jones', email: 'tjones@example.com'
)
johnson = Contact.create(
firstname: 'John', lastname: 'Johnson', email: 'jjohnson@example.com'
)
expect(Contact.by_letter("J")).to eq [johnson, jones]
end
end
-
自動的にテストが走り、失敗する
-
コードを書く
app/models/contact.rb
def self.by_letter(letter)
where("lastname LIKE ?", "#{letter}%").order(:lastname)
end
- 自動的にテストが走り、合格する
リファクタリング
before
とcontext
を使ってテストコードを整理する。
spec/models/contact_spec.rb
describe "filter last name by letter" do
before :each do
@smith = Contact.create(
firstname: 'John', lastname: 'Smith', email: 'jsmith@example.com'
)
@jones = Contact.create(
firstname: 'Tim', lastname: 'Jones', email: 'tjones@example.com'
)
@johnson = Contact.create(
firstname: 'John', lastname: 'Johnson', email: 'jjohnson@example.com'
)
end
context "matching letters" do
it "returns a sorted array of results that match" do
expect(Contact.by_letter("J")).to eq [@johnson, @jones]
end
end
context "non-matching letters" do
it "returns a sorted array of results that match" do
expect(Contact.by_letter("J")).to_not include smith
end
end
end
おしまい。
ブログやってます:PAPA-tronix !