RailsによるアジャイルWebアプリケーション開発

第7章 タスクB:検証とユニットテスト

validationのテストは面倒なので、shoulda-matchersで済ませてしまう。
これはそもそもRailsのテストになるので余計だ、という人もいるが、自分はぼけてるので書き間違え、設定し忘れがよくあるので書くようにする。
テストの設定(Gemfileなど)についてはEveryday Railsと同じ。

  • spec/models/product_spec.rb
require 'rails_helper'

RSpec.describe Product, type: :model do
  describe "validate" do
    it { is_expected.to validate_presence_of(:title) }
    it { is_expected.to validate_uniqueness_of(:title) }
    it { is_expected.to validate_presence_of(:description) }
    it { is_expected.to validate_presence_of(:image_url) }
    it {
      is_expected.to validate_numericality_of(:price)
        .is_greater_than_or_equal_to(0.01)
    }
    it "validate image_url" do
      ok = %w{
        fred.gif fred.jpg fred.png FRED.JPG FRED.Jpg
        http://a.b.c/x/y/z/fred.gif
      }
      ng = %w{ fred.doc fred.gif/more fred.gif.more }

      ok.each do |image_url|
        expect(build(:product, image_url: image_url).valid?).to be_truthy
      end

      ng.each do |image_url|
        expect(build(:product, image_url: image_url).valid?).to be_falsey
      end
    end
  end
end

第8章 タスクC:カタログの表示

p.98のViewに何が入ってるか、はControllerじゃなくてfeatureスペックに書いた方がいいかも、と思ったのでそっちで。

factoryでは画像は使い回し。

  • spec/factories/products.rb
FactoryGirl.define do
  factory :product do
    title { Faker::Lorem.sentence }
    description { Faker::Lorem.paragraph }
    image_url "ruby.jpg"
    price { rand(5.0..50.00).round(2) }
  end
end
  • spec/features/store_spec.rb
require 'rails_helper'

feature "Store" do
  feature "トップページ" do
    background do
      @product = create(:product)
      create_list(:product, 2)
    end

    scenario "商品が表示されていること", js: true do
      visit store_path

      expect(page).to have_selector("#columns #side li", count: 4)
      expect(page).to have_selector("#main .entry", count: 3)
      expect(page.all("h3").map(&:text)).to include @product.title
      expect(page.all(".price").first.text).to match /\$[,\d]+\.\d\d/
      save_screenshot(sc_path("store_1.png"))
    end
  end
end

sc_pathは自分で作った。Rails.root.join("screenshots", file_name) みたいに。
f:id:yossk:20141231162251p:plain

今日の感想

便利なgemを使わないと、Railsと言えどやはり面倒。
ただ、使い過ぎないようにしないといけない。