简体   繁体   English

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

[英]Why is this RSpec test failing?

I'm in the process of learning Ruby on Rails, so treat me like a total neophyte, because I am. 我正在学习Ruby on Rails,所以对待我就像一个完全新手,因为我。

I've got a User model with some associated RSpec tests, and the following test fails: 我有一个用户模型与一些相关的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

The relevant part of the User model looks like this: User模型的相关部分如下所示:

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

Here's the catch: if I run User.new(...).valid? 这是一个问题:如果我运行User.new(...).valid? from a Rails console using the arguments above, it returns false as expected and shows the correct errors (password is blank). 使用上面的参数从Rails控制台,它按预期返回false并显示正确的错误(密码为空)。

I was using spork/autotest and I restarted both to no avail, but this test also fails even running it directly with rspec . 我正在使用spork / autotest并且我重新启动两个都无济于事,但是这个测试也无法直接用rspec运行它。 What am I doing wrong here? 我在这做错了什么?

EDIT 编辑

I tried a few more things with the test. 我在测试中尝试了一些其他的东西。 This fails: 这失败了:

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

So does this: 这样做:

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

This passes, confirming that :password is indeed blank: 这传递,确认:password确实是空白的:

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

So, it's actually spork that is causing the problem. 所以,它实际上是导致问题的spork。 You can turn caching off, so that it won't need restarting every time : 您可以关闭缓存,以便每次都不需要重新启动:

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

I think this is what happens : 我想这就是:

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"], ...} 

In short, if you change new to create, it will work :) I think that this happens because the matcher be_valid checks on the model validation errors. 简而言之,如果您将new更改为create,它将起作用:)我认为这是因为匹配器be_valid检查模型验证错误。 There can be a deeper explanation, but i think that if you use create instead of new, it will work. 可以有更深层次的解释,但我认为如果你使用create而不是new,它会起作用。

EDIT : I have a be_valid_verbose version that might help. 编辑:我有一个be_valid_verbose版本,可能有所帮助。 Just create a 'be_valid_verbose.rb' file in your rspec/custom_matchers folder, and inside it write : 只需在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

Now check against be_valid_verbose instead of be_valid. 现在检查be_valid_verbose而不是be_valid。 It will hopefully present you with some more information on what is happening in your case. 它有望为您提供有关您案例中发生的事情的更多信息。

As I feared, the answer was stupidity. 我担心,答案是愚蠢的。 This was a spork problem. 这是一个棘手的问题。 I thought I had killed the existing process and was running rspec independently, but I later found the spork process still running in a different shell, and rspec had been connecting to it all along. 我以为我已经杀死了现有的进程,并且独立运行了rspec,但后来我发现spork进程仍在不同的shell中运行,并且rspec一直在连接它。 Restarting spork (or killing it entirely) and re-running the tests fixed the problem. 重新启动spork(或完全杀死它)并重新运行测试可以解决问题。

I found this particularly deceptive in that rspec continually updated the test output to reflect the fact that it was aware of my test changes, so it appeared to me that it was running against up-to-date code. 我发现这特别具有欺骗性,因为rspec不断更新测试输出以反映它知道我的测试更改的事实,所以在我看来它是在运行最新的代码。 Now I'm left to wonder what the real utility of spork is, since apparently I can't trust that it's actually running the right tests correctly. 现在我不知道spork的实用性是什么,因为显然我不相信它实际上正确地运行了正确的测试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM