補充: 使用 FactoryGirl 生假資料

在這個測試裡面,你可以見到我們直接產生了 course1course2 兩個 course。

require "rails_helper"

RSpec.describe CoursesController, type: :controller do
  describe "GET index" do
    it "assigns @courses and render template" do
      course1 = Course.create(title: "foo", description: "bar")
      course2 = Course.create(title: "bar", description: "foo")

      get :index

      expect(assigns[:courses]).to eq([course1,course2])
      expect(response).to render_template("index")
    end
  end
end

每次都要手動在測試裡面生假資料實在很麻煩。通常開發者會使用 FactoryGirlFabrication 這種專門生測試資料的 Gem 來大量生例子。

在這本書裡面,是使用 FactoryGirl這個 Gem 作為示範。

安裝 FactoryGirl

在 Gemfile 裡面加入

group :development, :test do
  gem "rspec-rails", "~> 3.5.2"
  gem "rails-controller-testing", "~> 1.0.1"
  gem "factory_girl_rails", "~> 4.7.0" # <--- 新增這一行
end

然後 bundle install 安裝這個 gem。

接著生成 FactoryGirl 的配置文件:

mkdir spec/support
touch spec/support/factory_girl.rb

編輯 spec/support/factory_girl.rb

RSpec.configure do |config|
  config.include FactoryGirl::Syntax::Methods # 在測試裡不需要使用 FactoryGirl
end

然後修改 spec/rails_helper.rb 加入一行

require 'spec_helper'
require 'rspec/rails'
# Add additional requires below this line. Rails is not loaded until this point!

Dir[Rails.root.join("spec/support/**/*.rb")].sort.each { |file| require file } # <-- 加入這一行

# Requires supporting ruby files with custom matchers and macros, etc, in

如何使用 Factory Girl

FactoryGirl 的檔案慣例是放在 spec/factories.rbtouch spec/factories.rb

定義一個 Course Factory:

FactoryGirl.define do
  factory :course do
    title "Course Name"
    description "Description."
  end
end

翻修 course controller 的 spec

最後可以把 spec/controllers/courses_controller_spec.rb 改成以下內容

require "rails_helper"

RSpec.describe CoursesController, type: :controller do
  describe "GET index" do
    it "assigns @courses and render template" do
      course1 = create(:course)
      course2 = create(:course)

      get :index

      expect(assigns[:courses]).to eq([course1, course2])
      expect(response).to render_template("index")
    end
  end
end

現在建立一個 course

Course.create(title: "foo", description: "bar")

只要

create(:course) # 等同於 FactoryGirl.create(:course)

即可,是不是很方便呢?

更多 FactoryGirl 的內容請參考附錄:《假資料,Faker 以及 FactoryGirl》。

results matching ""

    No results matching ""