Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
24
Help us understand the problem. What is going on with this article?
@Feel-Physics

RubyMineでRailsをテスト駆動開発(Rspec)してみる(1)

More than 5 years have passed since last update.
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

  1. コードを書く
Gemfile
group :development, :test do
  gem "rspec-rails"
  gem "factory_girl_rails"
end

group :test do
  gem "faker"
  gem "capybara"
  gem "database_cleaner"
end
  1. bundle install

  2. Tools > Run Rails Script > "rails", "generate rspec:install"

  3. Tools > Run Rails Generator > model > Contact firstname:string lastname:string email:string phone:references

  4. Tools > Run Rails Generator > model > Phone contact:references phone_type:string phone:string

  5. Tools > Run Rake Task > db:migrate

1st red

  1. テストを書く
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
  1. Run > Run > spec

pending

  1. Toggle auto-test

  2. テストを書く

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
  1. 保存すると自動でテストが走り、こける

  2. コードを書く

app/models/contact.rb
  validates :firstname, presence: true
  validates :lastname, presence: true
  validates :email, presence: true, uniqueness: true
  1. 保存すると自動でテストが走り、合格する

2nd red

  1. テストを書く
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
  1. 保存すると自動でテストが走り、pendingになる

  2. テストを書く

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
  1. 保存すると自動でテストが走り、こける

  2. コードを書く

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 }
  1. 保存すると自動でテストが走り、合格する

3rd red

  1. テストを書く
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

  1. Run > Run > spec

テストが走り、失敗する

  1. Toggle auto-test

  2. コードを書く

app/models/contact.rb
  def name
    [firstname, lastname].join " "
  end
  1. 自動的にテストが走り、合格する

4th red

  1. テストを書く
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
  1. 自動的にテストが走り、失敗する

  2. コードを書く

app/models/contact.rb
  def self.by_letter(letter)
    where("lastname LIKE ?", "#{letter}%").order(:lastname)
  end
  1. 自動的にテストが走り、合格する

リファクタリング

beforecontextを使ってテストコードを整理する。

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 !

24
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Feel-Physics
今はHoloLensのアプリを開発しており、技術記事はすべてブログ( http://weed.nagoya )に書いています。以前はSwift、OpenCV+Python、JavaScript、Objective-Cを書いていました。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
24
Help us understand the problem. What is going on with this article?