2012-07-27 40 views
23

我是使用RSpec在使用MySQL数据库的Rails应用程序中编写测试的新手。我定义我的灯具和我加载它们在我的规格如下:RSpec中的灯具

before(:all) do 
    fixtures :student 
end 

这是否申报保存在我的学生表灯具定义的数据还是只是加载表中的数据,而测试在所有测试运行后运行并将其从表中移除?

+10

取而代之的是灯具,请试试看[factory_girl](http://www.fabricationgem.org/)或[制造](http://www.fabricationgem.org/)。 – 2013-11-02 13:21:45

回答

-1

这取决于您配置RSpec的方式。有关更多详细信息,请参见here

1

before(:all)保留确切的数据,因为它已加载/创建一次。你做你的事情,并在测试结束时停留。这就是为什么bui的链接有after(:all)销毁或使用before(:each); @var.reload!;end从以前的测试中获取最新的数据。我可以看到在嵌套rspec描述块中使用这种方法。

16

如果你想块前使用与RSpec的固定装置,在描述块指定赛程,不是内:

describe StudentsController do 
    fixtures :students 

    before do 
    # more test setup 
    end 
end 

您的学生灯具将被装载到学生表,然后在回滚使用数据库事务结束每个测试。

+1

https://www.relishapp.com/rspec/rspec-rails/docs/model-specs/transactional-examples#run-in-transactions-with-fixture – nruth 2015-01-10 03:06:44

3

首先:您不能在:all/:context/:suite hook中使用方法fixtures。不要试图在这些挂钩中使用灯具(如post(:my_post))。

您可以仅在describe/context块中准备Fixtures,因为Infuse先前写入。

呼叫

fixtures :students, :teachers 

任何数据不加载到数据库!只准备帮手方法studentsteachers。 当您首次尝试访问它们时,需要的记录会被懒惰地加载。之前

dan=students(:dan) 

这会加载学生和老师delete all from table + insert fixtures的方式。

所以,如果你准备在之前(:上下文)钩一些学生,他们将会消失!

插入记录只在测试套件中完成一次。

来自灯具的记录在测试套件结束时不会被删除。在下一次测试套件运行时,它们将被删除并重新插入。

例如:

#students.yml 
    dan: 
    name: Dan 
    paul: 
    name: Paul 

#teachers.yml 
    snape: 
     name: Severus 




describe Student do 
    fixtures :students, :teachers 

    before(:context) do 
    @james=Student.create!(name: "James") 
    end 

    it "have name" do 
    expect(Student.find(@james.id).to be_present 
    expect(Student.count).to eq 1 
    expect(Teacher.count).to eq 0 

    students(:dan) 

    expect(Student.find_by_name(@james.name).to be_blank 
    expect(Student.count).to eq 2 
    expect(Teacher.count).to eq 1 

    end 
end 


#but when fixtures are in DB (after first call), all works as expected (by me) 

describe Teacher do 
    fixtures :teachers #was loade in previous tests 

    before(:context) do 
    @james=Student.create!(name: "James") 
    @thomas=Teacher.create!(name: "Thomas") 
    end 

    it "have name" do 
    expect(Teacher.find(@thomas.id).to be_present 
    expect(Student.count).to eq 3 # :dan, :paul, @james 
    expect(Teacher.count).to eq 2 # :snape, @thomas 

    students(:dan) 

    expect(Teacher.find_by_name(@thomas.name).to be_present 
    expect(Student.count).to eq 3 
    expect(Teacher.count).to eq 2 

    end 
end 

在测试的所有预期以上将通过

如果这些测试中(在接下来的套件)和以该顺序再次运行,比预期

expect(Student.count).to eq 1 

将不会被满足!将有3名学生(:丹,:保罗和新鲜的@james)。所有这些将在students(:dan)之前被删除,并且只有:paul和:dan会再次被插入。

+1

是啊!我发现了在所有测试之前加载所有灯具的技巧。只需添加RSpec.configure {| config | config.global_fixtures =:all}并直接在spec_helper中测试,它将尝试访问任何灯具。这样所有的灯具都会提前加载。 – Foton 2016-09-29 14:14:11