【问题标题】:Mongoid Model.find fails in spec, but works in appMongoid Model.find 在规范中失败,但在应用程序中有效
【发布时间】:2014-04-05 05:40:05
【问题描述】:

下一行:

  User.find(session[:user_id])

其中session[:user_id]先前定义:

  session[:user_id] = user.id

在规范中工作正常并返回用户模型,但在实际应用程序(开发模式)中失败:

MOPED: 127.0.0.1:27017 QUERY        database=rails_api_development collection=users selector={"_id"=>{"$oid"=>BSON::ObjectId('533c3958616c641142010000')}} flags=[] limit=0 skip=0 batch_size=nil fields=nil runtime: 1.0680ms
Completed 500 Internal Server Error in 15ms

Moped::Errors::QueryFailure - The operation: #<Moped::Protocol::Query
    @length=89
@request_id=2
@response_to=0
@op_code=2004
@flags=[]
@full_collection_name="rails_api_development.users"
@skip=0
@limit=0
@selector={"_id"=>{"$oid"=>BSON::ObjectId('533c3958616c641142010000')}}
@fields=nil>
    failed with error 10068: "invalid operator: $oid"

See https://github.com/mongodb/mongo/blob/master/docs/errors.md
for details about this error.:
  moped (2.0.0.rc1) lib/moped/operation/read.rb:50:in `block in execute'
  moped (2.0.0.rc1) lib/moped/node.rb:594:in `block (2 levels) in flush'

full log

当我将find 更改为:

  User.find(session[:user_id]['$oid'])

但规范失败:

   1) ApplicationController current_user when current_user is nil and user_id stores in session finds and returns it from db
 Failure/Error: expect(subject.send(:current_user)).to eq user
 NoMethodError:
   undefined method `[]' for BSON::ObjectId('533fae9e616c6464a4010000'):BSON::ObjectId
 # ./app/controllers/application_controller.rb:7:in `current_user'
 # ./spec/controllers/application_controller_spec.rb:22:in `block (5 levels) in <top (required)>'

在规范中,我正在使用真正的数据库,使用 database_cleaner。所以,我猜都一样(但显然不是)

My gemfile

我尝试为user_id according to this 制作to_sto_json,添加mongoid 初始化文件with this,还尝试更改multi_json moped 版本 - 没有帮助。

我的应用程序控制器规格为 there

考虑到以前这些棘手问题的结果,我勉强希望有人能提供帮助,但无论如何,提前谢谢!

更新: 测试失败:

context "when current_user is nil" do
  context "and user_id stores in session" do
    let(:user) { create(:user) }
    before { allow(subject).to receive(:session).and_return({ user_id: user.id }) }
    before { allow(User).to receive(:find).and_return(user) }

    it "finds and returns it from db" do
      expect(User).to receive(:find)
>     expect(subject.send(:current_user)).to eq user
    end
  end

【问题讨论】:

  • 请贴出失败的相关测试

标签: ruby-on-rails ruby rspec mongoid bson


【解决方案1】:

我之前也遇到过类似的问题,问题是会话中BSON::ObjectId 的json 表示。您还发现,致电to_s 为我解决了这个问题。您需要确保会话包含字符串格式的 id。因此,每当您将用户 ID 分配给会话时,请致电 to_s。尝试进行以下更改:

ApplicationController 中的current_user= 更改为:

def current_user=(user)
  @current_user = user
  session[:user_id] = user.try(:id).try(:to_s)
end

将规范更改为:

context "and user_id stores in session" do
  let(:user) { create(:user) }
  before { allow(subject).to receive(:session).and_return({ user_id: user.id.to_s }) }
  before { allow(User).to receive(:find).and_return(user) }

  it "finds and returns it from db" do
    expect(User).to receive(:find)
    expect(subject.send(:current_user)).to eq user
  end
end

【讨论】:

  • 我也去掉了before { allow(User).to receive(:find).and_return(user) },所以没必要,把期望改成expect(User).to receive(:find).and_return(user)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-09
相关资源
最近更新 更多