链接ActiveRecord范围会导致[]:Array的未定义方法

时间:2014-07-21 14:05:18

标签: ruby-on-rails activerecord rspec rspec2 ruby-on-rails-4.1

我只在RSpec的测试环境中出现此错误。该代码适用于所有其他环境,包括Rails控制台。

鉴于此代码

class User < ActiveRecord::Base
  scope :flag, -> {where(flag: nil) } 
end

当我致电User.where(expired_at: nil).flag

然后它会生成undefined method标记for []:Array

我正在使用Rails 4.1.1和rspec-rails 2.14.0。

2 个答案:

答案 0 :(得分:0)

使用该存根,您的“User.where(expired_at:nil)”将返回[],您的代码将采用[],然后尝试在其上调用“flag”。由于Ruby中的数组没有名为“flag”的方法,因此您看到的异常会被抛出。有几种方法可以解决这个问题。

1)不要将该呼叫存根。让框架处理它(是的,它会尝试命中数据库,这可能是你想要避免的,但仍然是,它是一个选项)。

2)返回测试双精度而不是空数组,如

results = double(:expired_users, flag: [])
User.stub(:where).and_return(expired_users)

在“:expired_users”上查看如何将标记存根到返回空数组?

3)向您的用户模型添加一个方法,该方法基本上可以运行您想要的内容并将其存根,例如:

class User
  def self.flagged_expired_users
    where(expired_at: nil).flag
  end
end

和规范

User.stub(:flagged_expired_users).and_return([])

我自己更喜欢#3,因为在我的体验中,测试/模拟的风格往往不那么脆弱,但是ymmv。

答案 1 :(得分:-1)

在我的RSpec示例中,我呼叫User.stub(:where).and_return([])

我将其替换为User.stub(:where).and_return(User.all)