为什么这个RSpec测试失败了?

时间:2011-05-11 04:46:18

标签: ruby-on-rails rspec

我正在学习Ruby on Rails,所以对待我就像一个全新的人,因为我。

我有一个带有一些相关RSpec测试的用户模型,以下测试失败:

require 'spec_helper'
describe User do

    it 'should require a password' do
        User.new({:email => 'valid_email@example.com', :password => '', :password_confirmation => ''}).should_not be_valid
    end

end

User模型的相关部分如下所示:

class User < ActiveRecord::Base
    ...
    validates :password, :presence => true,
                         :confirmation => true,
                         :length => { :minimum => 6 }
    ...
end

这是一个问题:如果我使用上面的参数从Rails控制台运行User.new(...).valid?,它会按预期返回false并显示正确的错误(密码为空)。

我正在使用spork / autotest并且我重新启动两个都无济于事,但是这个测试也无法直接用rspec运行它。我在这里做错了什么?

修改

我在测试中尝试了更多的东西。这失败了:

        u = User.new({:email => 'valid_email@example.com', :password => '', :password_confirmation => ''})
        u.should_not be_valid

这样做:

        u = User.new({:email => 'valid_email@example.com', :password => '', :password_confirmation => ''})
        u.valid?
        u.errors.should_not be_empty

这通过,确认:password确实是空白的:

        u = User.new({:email => 'valid_email@example.com', :password => '', :password_confirmation => ''})
        u.password.should == ''

2 个答案:

答案 0 :(得分:2)

所以,它实际上是导致问题的spork。您可以关闭缓存,以便每次都不需要重新启动:

http://ablogaboutcode.com/2011/05/09/spork-testing-tip-caching-classes

我认为这是发生的事情:

ruby-1.9.2-p180 :020 > u = User.new
 => #<User id: nil, email: ...
ruby-1.9.2-p180 :021 > u.errors
 => {} 
ruby-1.9.2-p180 :022 > u.save
 => false 
ruby-1.9.2-p180 :023 > u.errors
 => {:email=>["can't be blank", "can't be blank"], ...} 

简而言之,如果你将new更改为create,它将会工作:)我认为这是因为匹配器be_valid检查模型验证错误。可以有更深层次的解释,但我认为如果你使用create而不是new,它将起作用。

编辑:我有一个be_valid_verbose版本,可能有所帮助。只需在rspec / custom_matchers文件夹中创建一个'be_valid_verbose.rb'文件,然后在其中写下:

RSpec::Matchers.define :be_valid_verbose do
  match do |model|
    model.valid?
  end

  failure_message_for_should do |model|
    "#{model.class} expected to be valid but had errors:n #{model.errors.full_messages.join("n ")}"
  end

  failure_message_for_should_not do |model|
    "#{model.class} expected to have errors, but it did not"
  end

  description do
    "be valid"
  end
end

现在检查be_valid_verbose而不是be_valid。希望能够为您提供有关您案件中发生的事情的更多信息。

答案 1 :(得分:0)

我担心,答案是愚蠢的。这是一个棘手的问题。我以为我已经杀死了现有的进程,并且独立运行了rspec,但后来我发现spork进程仍在不同的shell中运行,并且rspec一直在连接它。重新启动spork(或完全杀死它)并重新运行测试可以解决问题。

我发现这特别具有欺骗性,因为rspec不断更新测试输出以反映它知道我的测试更改的事实,所以在我看来它是在运行最新的代码。现在我不知道spork的实用性是什么,因为显然我不相信它实际上正确地运行了正确的测试。