rspec的行为与FactoryGirl一起使用

mus*_*oom 1 rspec factory-bot

我正在尝试使用FactoryGirl为我的一个控制器规格创建一些项目:

摘录:

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
Run Code Online (Sandbox Code Playgroud)

当我将let更改为:

before(:each) do
    @item1 = Factory(:item)
    @item2 = Factory(:item)
end
Run Code Online (Sandbox Code Playgroud)

我把@s放在变量前面,一切正常.为什么版本没有让我们工作?我尝试更改let让我们看到相同的行为.

Muh*_*ais 7

let(:item1) { FactoryGirl.create(:item) }
let(:item2) { FactoryGirl.create(:item) }
Run Code Online (Sandbox Code Playgroud)

实际上当你让它(:item1)它会进行延迟加载时,在内存中创建对象但不保存在数据库中,当你做

@item1 = Factory(:item)
Run Code Online (Sandbox Code Playgroud)

它将在数据库中创建对象.

试试这个:

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
Run Code Online (Sandbox Code Playgroud)

如果你不调用它将永远不会被实例化,而在每次方法调用之前强制评估(: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
Run Code Online (Sandbox Code Playgroud)