我正在阅读 6.3 版 Michael Hartel 的 rails 教程,需要 user_spec 模型的替代代码。他拥有的代码是:
let(:found_user) { User.find_by(email: @user.email) }
看起来我可以使用 where,但不确定语法是否正确。我尝试了以下几种变体:
let(:found_user) { User.where(:email => "@user.email")}
我确信这是一个非常简单的答案,但不能完全理解。
我正在阅读 6.3 版 Michael Hartel 的 rails 教程,需要 user_spec 模型的替代代码。他拥有的代码是:
let(:found_user) { User.find_by(email: @user.email) }
看起来我可以使用 where,但不确定语法是否正确。我尝试了以下几种变体:
let(:found_user) { User.where(:email => "@user.email")}
我确信这是一个非常简单的答案,但不能完全理解。
let(:found_user){User.where(email: @user.email).first}
或者
let(:found_user){User.find_by_email(@user.email)}
使用的第一个where
返回与 where 子句匹配的用户集合,这就是您需要它的原因.first
(它不会执行 sql,直到您使用 , 或 之类的内容获取.all
记录.first
).each
。
我会说在单元测试中执行数据库命令不是最佳实践。你具体测试什么?您是否有理由需要将用户保存在数据库中并且不能只执行以下操作:
let(:user){User.new(email: 'some email')}
ActiveRecord::Base#find_by
是有效where(options).first
的,但这是一个你不需要做的额外调用。
Rails 还提供了一些不推荐使用的“魔法”find_by_<attribute>[and_<attribute>]
方法,这些方法用于method_missing
根据方法的名称解析出其含义。虽然框架确实提供了这些,但我警告不要使用它们,因为它们必然比“本机”方法慢,并且更难以重构。
对于一般情况,我建议坚持使用find_by
,并尽量避免在规范和测试中触及数据库。
factory_girl gem提供了一种方法来创建类的存根版本,该版本通过回答并true
提供.persisted?
id
或者,您可以只构建一个新记录而不保存它:User.new(attribute: value, ...)
并在其上运行您的测试:
it "does some things" do
user = User.new(attributes)
# make user do some things
expect(things).to have_happened
end