GMA*_*GMA 8 unit-testing rspec ruby-on-rails factory-bot
说我有机型User和Post,用户has_many的职位和岗位belongs_to的用户.
当我写一个规范时Post,我的第一直觉是写这样的东西:
before do
@user = FactoryGirl.create :user
@post = @user.posts.new(title: "Foo", content: "bar)
end
... tests for @post go here ...
Run Code Online (Sandbox Code Playgroud)
但这将创建一个新的用户 - 命中数据库 - 对于每一次测试,这将减慢速度.有没有更好的方法来加快我的测试速度并避免频繁击中数据库?
据我所知,我不能使用FactoryGirl.build :user因为,即使它不会打到数据库,关联也无法正常工作,因为@user没有ID,所以@post.user不会工作(它返回nil.)
我可以使用FactoryGirl.build_stubbed :user哪个创建了一个"假@user持有" ,它有一个ID,但@post.user仍然返回nil.当我测试与协会有关的事情时,是否build_stubbed有任何实际优势build?
我想我可以使用build_stubbed存根,@post.user所以它返回@user...有什么理由这可能是个坏主意吗?
或者我应该使用create并接受速度命中?
我能想到的唯一另一种选择是在一个before(:all)块中设置@user 似乎是一个坏主意.
以简洁明了的方式编写这类测试的最佳方法是什么,避免进行过多的数据库查询?
ush*_*sha 18
如果您不希望您的测试访问数据库,那么您就必须这样做.
before do
@user = FactoryGirl.build_stubbed :user
@post = FactoryGirl.build_stubbed :post
@user.stub(:posts).and_return([@post])
@post.stub(:user).and_return(@user)
end
Run Code Online (Sandbox Code Playgroud)
注意:使用时要小心before(:all).它不会在事务中执行.因此,无论您创建什么,before(:all)都会留在数据库中,并可能导致与其他测试冲突
关于FactoryGirl.build,它构建对象,但创建关联.
例如:
factory :user do
association posts
end
FactoryGirl.build(:user) #this creates posts in the database even though you are only building the parent object(user)
Run Code Online (Sandbox Code Playgroud)
Joe*_*ris 15
简答
@user = FactoryGirl.build_stubbed(:user)
@post = FactoryGirl.build_stubbed(:post, :user => @user)
Run Code Online (Sandbox Code Playgroud)
这将使@ post.user工作,而不会访问数据库.
答案很长
我的建议是等待before你确定你需要它.相反,为每个单独的测试构建所需的数据,并在找到时将重复提取到方法或新工厂.
另外,您是否真的需要在每次测试中引用用户?有@user在每个测试可说给其他开发者,它是重要的无处不在.
最后,假设用户关联在您的文章的工厂也宣告,你会自动获得一个工作post.user,当你做build_stubbed(:post).
它可以很容易忘记之间的差异create,build以及build_stubbed.以下是相同情况下的快速参考(因为此页面在搜索结果中排名很高).
# Returns a User instance that's not saved (does not write to DB)
user = build(:user)
# Returns a saved User instance (writes to DB)
user = create(:user)
# Returns a hash of attributes that can be used to build a User instance
attrs = attributes_for(:user)
# Returns an object with all defined attributes stubbed out
stub = build_stubbed(:user)
# Passing a block to any of the methods above will yield the return object
create(:user) do |user|
user.posts.create(attributes_for(:post))
end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5364 次 |
| 最近记录: |