Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 当我以这种方式使用FactoryGirl时,为什么我的测试失败?_Ruby On Rails_Ruby On Rails 3_Factory Bot_Rspec Rails - Fatal编程技术网

Ruby on rails 当我以这种方式使用FactoryGirl时,为什么我的测试失败?

Ruby on rails 当我以这种方式使用FactoryGirl时,为什么我的测试失败?,ruby-on-rails,ruby-on-rails-3,factory-bot,rspec-rails,Ruby On Rails,Ruby On Rails 3,Factory Bot,Rspec Rails,我正在测试我的用户模型,研究FactoryGirl是如何工作的。当我在我的用户规范rb中执行此操作时: before(:each) do @user = User.new(username: 'ExampleUser', email: 'user@example.com', timezone: 'Eastern Time (US & Canada)', password: 'example') end 一切都过去了,但如果我做到了: before(:each) do @user

我正在测试我的用户模型,研究FactoryGirl是如何工作的。当我在我的用户规范rb中执行此操作时:

before(:each) do
  @user = User.new(username: 'ExampleUser', email: 'user@example.com', timezone: 'Eastern Time (US & Canada)', password: 'example')
end
一切都过去了,但如果我做到了:

before(:each) do
  @user = FactoryGirl.create(:user)
end
测试失败,无法查看用户的用户名和电子邮件是否已被占用

1) User when username is already taken
     Failure/Error: it { should_not be_valid }
       expected valid? to return false, got true
     # ./spec/models/user_spec.rb:151:in `block (3 levels) in <top (required)>'

  2) User when email address is already taken
     Failure/Error: it { should_not be_valid }
       expected valid? to return false, got true
     # ./spec/models/user_spec.rb:142:in `block (3 levels) in <top (required)>'

Finished in 1.8 seconds
29 examples, 2 failures

有人能解释一下吗?我认为FactoryGirl应该让我像使用用户一样使用它。new,这是我第一个有效的示例。

FactoryGirl.create
实际上创建了记录,而User.new只实例化了模型,但实际上并没有保存记录

如果只想实例化模型,则应使用
FactoryGirl.build

before(:each) do
  @user = FactoryGirl.build(:user)
end
有关详细信息,请参阅

因此,我认为当前代码的情况是,当您使用
FactoryGirl.create
创建用户时,它实际上保存了记录,没有任何验证问题(因为尚未创建副本)。当您使用
user\u with\u same\u email.save
以相同的电子邮件保存用户时,它实际上不会保存该用户,但您看不到。然后,当您检查原始用户是否有效时,它会说是,因为您在尝试(但失败)创建副本之前已经保存了它


有道理吗?无论如何,只要切换到
FactoryGirl.build
,两个测试都应该通过。

通常,当使用Factory Girl测试一个字段时,该字段具有
验证的唯一性时,最好使用

使用序列时,每次使用
FactoryGirl.create(:user)
创建记录时,用户名将始终是唯一的。这允许您处理数据库中的“真实”记录,而无需手动更正冲突值

factory :user do
  sequence :username do |n}
    "user_#{n}"
  end
end
注意:我不喜欢测试尚未添加到数据库中的记录。我想不出任何确切的理由来解释为什么这会成为一个问题。我能想到的唯一问题是,您将无法测试关联


我一直注意到的另一个问题是在
块之前使用
,并创建实例变量。在RSpec中,有一个名为
let
的方法将在需要时创建变量

这将使您的
user_spec.rb
文件像这样工作

describe User do
  let(:user) { create(:user, :first_name => "John", :last_name => "Doe") }

  it "should get full name" do
    user.full_name.should == "John Doe"
  end
end

let
还有一个bang方法,该方法将创建变量,无论它是否在
it
块中使用。

您是否在每个测试示例之前使用类似数据库清理器()的东西重置DB?我明白您所说的创建和所有,但在逻辑上没有意义。FactoryGirl.create(:user)应该先在数据库中生成user.first,然后blah=@user.dup,他完成了他的任务,然后blah.save!应该抛出一个错误。如果不是,这个工厂女孩有什么好处?我知道我和我们的OP一样也有这个问题,这对我来说毫无意义,让我发疯。我的意思是,在现实生活中,他可以在控制台中执行,他会得到一个错误,所以他的测试应该反映出这一点,依我看。我不明白你为什么说,原始文件保存后会检查其有效性?我认为它是
@user=FG.create#保存好。b=@user.dup#复制相同的对象。b、 email=@user.email.upcase#将其更改,但仍保持不变;b、 救命应引发验证错误。我只是在控制台中尝试了这一点,但没有使用FG.create,而是使用了my User.first。@pjammer我想您可能混淆了规范中验证错误的检查内容。在
中{should\u not\u valid}
主题是
@user
,而不是
user\u with\u same\u email
user\u with\u same\u username
<代码>废话。保存
会抛出一个错误,但他没有发出砰的一声就调用了它,所以它不会抛出错误,只是无法保存(静默)。重复一下,
b.save
会抛出一个错误,但他正在调用
b.save
,它会无声地失败。那么他的测试也是错误的吗?你说得对,我对it行的理解不够,但他不想确保用户名相同的用户无效吗?这样测试工厂有什么好处?
describe User do
  let(:user) { create(:user, :first_name => "John", :last_name => "Doe") }

  it "should get full name" do
    user.full_name.should == "John Doe"
  end
end