1

FactoryGirlを使用して、コントローラー仕様の1つにいくつかのアイテムを作成しようとしています。

抜粋:

describe ItemsController do
    let(:item1){Factory(:item)}
    let(:item2){Factory(:item)}

    # This fails. @items is nil because Item.all returned nothing
    describe "GET index" do
        it "should assign all items to @items" do
            get :index
            assigns(:items).should include(item1, item2)
        end
    end

    # This passes and Item.all returns something 
    describe "GET show" do
        it "should assign the item with the given id to @item" do
            get :show, id => item1.id 
            assigns(:item).should == item1
        end
    end
end

レットをこれに変更すると:

before(:each) do
    @item1 = Factory(:item)
    @item2 = Factory(:item)
end

変数の前に@sを付けると、すべてが機能します。なぜlet付きのバージョンが機能しないのですか?letsをlet!sに変更してみたところ、同じ動作が見られました。

4

1 に答える 1

8
let(:item1) { FactoryGirl.create(:item) }
let(:item2) { FactoryGirl.create(:item) }

実際に let(:item1) を実行すると、遅延読み込みが実行され、メモリ内にオブジェクトが作成されますが、データベースには保存されません。

@item1 = Factory(:item)

データベースにオブジェクトを作成します。

これを試して:

describe ItemsController do
    let!(:item1){ Factory(:item) }
    let!(:item2){ Factory(:item) }

    describe "GET index" do
        it "should assign all items to @items" do
            get :index
            assigns(:items).should include(item1, item2)
        end
    end

    describe "GET show" do
        it "should assign the item with the given id to @item" do
            get :show, id => item1.id 
            assigns(:item).should == item1
        end
    end
end

let は呼び出さないとインスタンス化されませんが、 (:let!) は各メソッド呼び出しの前に強制的に評価されます。

またはこれを行うことができます:

describe ItemsController do
    let(:item1){ Factory(:item) }
    let(:item2){ Factory(:item) }

    describe "GET index" do
        it "should assign all items to @items" do
            item1, item2
            get :index
            assigns(:items).should include(item1, item2)
        end
    end

    describe "GET show" do
        it "should assign the item with the given id to @item" do
            get :show, id => item1.id 
            assigns(:item).should == item1
        end
    end
end
于 2012-12-29T06:46:34.130 に答える