在分析由Mongoid事件生成的ActiveRecord对象时,Rspec测试随机失败

Sak*_*kin 5 activerecord rspec ruby-on-rails mongodb

我实现了一个基于Mongoid的活动日志记录机制,可以在MongoDB中保存事件.

Mongoid模型Activity具有after_create根据记录的活动类型执行不同任务的事件:(简化示例)

class Activity
  include Mongoid::Document

  after_create do |activity|
    method_name = "after_#{activity.event_type}"
    send(method_name) if respond_to? method_name
  end

  def after_user_did_something
    MyItem.create!(:type => :user_did_something)
  end
end
Run Code Online (Sandbox Code Playgroud)

测试看起来像这样:

 it 'should hide previous [objects] create a new updated one' do
      2.times do 
        user.log_activity(:user_did_something) 
      end
      items = MyItems.where(:type => :user_did_something)
      items.count.should == 2
    end
 end
Run Code Online (Sandbox Code Playgroud)

有时,测试失败items.count为0而不是2.只有在从命令行运行时才会发生这种情况,它只在运行rspec spec 此测试时或在使用Guard运行所有测试时才会发生.

Old*_*Pro 4

在典型的 Mongodb 设置中,数据库写入成功返回与可以读取数据之间可能存在延迟。有两个原因:

  • 为了提高性能,可以在将数据提交到磁盘之前返回“不安全”写入。
  • Mongodb使用副本集,存在复制延迟。通常,读取会作为负载平衡的一种形式分发到副本,因此即使您使用安全写入,您也可能从与刚刚写入的服务器不同的服务器读取数据,因此看不到刚刚写入的数据。

为了确保您始终可以立即读回刚刚使用 Mongoid 写入的数据,您需要设置数据库会话选项consistency: :strong, safe: true,这两个选项都不是默认的。