Rspec和Devise 4.2:过去工作的模型测试中的ArgumentError

时间:2016-07-12 02:07:17

标签: ruby-on-rails rspec rspec-rails ruby-on-rails-5

Rails 5现已推出,我正在升级我的基本登录/ CRUD应用程序以使用新框架,其中包括将Devise更新到4.2。除了一个失败的rspec测试外,事情非常简单。我尝试使用pry单步执行代码,但发现问题超出了我的范围。任何指针都会受到赞赏。

这是错误:

Failures:

1) User email rejects email addresses with improper format
   Failure/Error: expect(user).not_to be_valid

 ArgumentError:
   wrong number of arguments (given 0, expected 1)
 # ./spec/models/problem_test_user_spec.rb:13:in `block (4 levels) in <top (required)>'
 # ./spec/models/problem_test_user_spec.rb:11:in `each'
 # ./spec/models/problem_test_user_spec.rb:11:in `block (3 levels) in <top (required)>'

这是一个简化的测试:

 1  require 'rails_helper'
 2  require 'devise'
 3  
 4  RSpec.describe User, type: :model do
 5    let (:user) { FactoryGirl.create :user }
 6  
 7    describe "email" do
 8      it "rejects email addresses with improper format" do
 9        invalid_addresses = %w[ user@example,com user_at_foo.org user.name@example. ]
10  
11        invalid_addresses.each do |addr|
12          user.email = addr
13          expect(user).not_to be_valid
14        end
15      end
16    end
17  end

这是我的模特:

class User < ApplicationRecord
  devise :database_authenticatable, :validatable

  validates :email, length: { maximum: 254 } # max length per RFC 3696, errata ID 1690
end

这是我的工厂:

FactoryGirl.define do
  factory :user do
    name      { Faker::Name.name }
    tone_name { "#{Faker::Company.name} Tone" }
    email     { Faker::Internet.email }
    password              SOME_PASSWORD
    password_confirmation SOME_PASSWORD
    admin      false
  end
end

一个附言:应用程序在我的开发环境中正常运行,但它将允许name@example,com形式的无效密码,其中rails 4.2版本通过rspec测试并使用以下方法捕获此无效密码错误。

另一个线索:我了解到Devise将默认的email_regexp更改为v4.1中不太严格的表达式。我的测试实际上是失败的,因为现在接受了以前被识别为非法的电子邮件地址。 ArgumentError不在我的代码中。我认为这在Devise或Rspec中都是错误的。如果我在我的测试中添加binding.pry,那么我模型上的简单#inspect会导致以下情况:

    12:       invalid_addresses.each do |addr|
    13:         user.email = addr
    14:         binding.pry
 => 15:         expect(user).not_to be_valid
    16:       end
    17:     end
    18:   end
    19: end

[1] pry(#<RSpec::ExampleGroups::User::Email>)> user.inspect
ArgumentError: wrong number of arguments (given 0, expected 1)
from /Users/tarsa/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/devise-4.2.0/lib/devise/models/database_authenticatable.rb:146:in `password_digest'

Devise代码看起来没有错,我怀疑与ActiveRecord的某些交互正在进行,但此时我的调试技能已达到极限。

我可以通过将Devise配置为使用email_regexp的4.0.3版本来解决此问题。如果所有的密码字符串都被识别为无效,那么无论在哪里,该错误都不会被发现。

1 个答案:

答案 0 :(得分:1)

问题不在于Rails 5问题,但结果是我在我的模型中继续使用password_digest,该模型最初是使用ActiveRecord验证的。当我切换到Devise时,我将这个属性留在了表格中。从Devise 4.2.0开始,验证完成的机制已更改为使用serializable_hash,并且尝试将vestigal password_digest属性作为方法调用,从而导致错误。

删除字段消除了问题,测试失败并显示正确的消息。

感谢Devise的人们对此有所了解。