lxyuma BLOG

開発関係のメモ

factory_girl in rails3その1

factory_girlって何?

testデータを作ってくれるrubyのgem



なんで必要なのかと言うと、

  1. fixtureだけだと、融通が利かず結局、テストソースにテストデータをガリガリ書く羽目になって、
  2. ある程度量が増えた時にカラム変更しますとか言うと、テストソースに書いたテストデータの修正量が恐ろしい事になるので、(つい先日経験したXoX)

(直接テストソース書く方向でも、共通化しろよっていうのもあるけど)

=>これを回避するために、factory girl使う。(勿論、他にもメリットあるだろうけど。)

なぜ、回避できるかというと、

  1. テストデータをrubyで書くから結構融通が利く。

例えば、fixtureだと、勝手にsaveされたデータしか使えないけど、

factory girlだと、save前のデータも自由に使える。とかね。。。

だから、validate系のテストでもsave系のテストと同じようなデータで済んで、統一してテストデータが管理できるという感じ。


  • 公式

https://github.com/thoughtbot/factory_girl
https://github.com/thoughtbot/factory_girl/blob/master/GETTING_STARTED.md

  • 入門

このスライドシェア面白かった。
http://www.slideshare.net/suchi/factorygirl

※ちょい古め
http://www.func09.com/wordpress/archives/532#more-532



注意。

  • factory_girlと、
  • factory_girl_railsというものがあって、

rails3で使うのは、後者なので、注意。




やってみる

project作る。

$ rails new jikken1201
$ cd jikken1201


Gemfileに以下を追加して、

factory girlをインストールする

gem "factory_girl_rails", "~> 4.0"


にょろって何やねん。。

$ bundle install

....略

Installing factory_girl (4.1.0)
Installing factory_girl_rails (4.1.0)

入ってますね。

factory_girl_rails入れると、

factory_girl自体も入れてくれるみたいですね。


基本ページ作る。

今回は、

User:blog = 1:n

なる関係のテーブル(とMVC各ファイル)を2つ作る。

$ rails g scaffold user name:string
$ rails g scaffold blog title:string description:string user_id:integer

ここで、factory_girlをインストールしていると、

test/factories配下に

以下のファイルができている。

※以下はblogs.rbだが、users.rbも出来てるはず。

# Read about factories at https://github.com/thoughtbot/factory_girl

FactoryGirl.define do
  factory :blog do
    title "MyString"
    description "MyString"
    user_id 1
  end
end

こいつが、デフォルトのfixtureの代わりになるもの

ここからは、元のソースの準備に戻る。

user/blogのモデルクラスに関連を追記

class User < ActiveRecord::Base
  attr_accessible :name
  has_many :blogs
end

class Blog < ActiveRecord::Base
  attr_accessible :description, :title, :user_id
  belongs_to :user
end


ここからが、本番

さっそく、テストコードから、factory_girlを呼び出す。

require 'test_helper'

class BlogTest < ActiveSupport::TestCase
  test "success saving" do
    @blog = FactoryGirl.build(:blog)
    assert @blog.save
  end
end

なんでもないテストだが、これで通る。

少し、細かく見てみる

FactoryGirlでbuild/createメソッド

    @blog = FactoryGirl.build(:blog)
  • build

このメソッドは、保存前のインスタンスを取得するそう。

引数は、さっきのfactoriesのファイルのfactoryの後ろの名前ね。

  • create

逆にfixtureみたいに、保存後のインスタンス欲しい時は、buildでなく

createメソッドを使うといいらしい。



注意

昔の本、ブログを参考にしていると、

Factory.buildとか書いてあって、

それだと、動かないので、注意な。



次の記事で、関連を作ってみる。