Ruby on rails 如何使用rspec测试Mongoid::Observer

Ruby on rails 如何使用rspec测试Mongoid::Observer,ruby-on-rails,ruby,rspec,mongoid,observer-pattern,Ruby On Rails,Ruby,Rspec,Mongoid,Observer Pattern,在一个简单的mongoid数据模型上,如果用户有很多评论,我想在用户写至少一条评论时授予他一个特定的徽章。所以我设置了一个这样的观察者: class CommentBadgeObserver < Mongoid::Observer observe :comment def after_create(comment) CommentBadge.check_conditions_for(comment.user) end end class CommentBadge &

在一个简单的mongoid数据模型上,如果用户有很多评论,我想在用户写至少一条评论时授予他一个特定的徽章。所以我设置了一个这样的观察者:

class CommentBadgeObserver < Mongoid::Observer
  observe :comment

  def after_create(comment)
    CommentBadge.check_conditions_for(comment.user)
  end
end

class CommentBadge < Badge
  def self.check_conditions_for(user)
    if user.comments.size > 1
      badge = CommentBadge.create(:title => "Comment badge")
      user.award(badge)
    end
  end
end

验证此行为的最佳方法是什么?

我已经对您的代码进行了独立的修改(见下文)。我必须做三个小改动,才能让它按你期望的方式工作

要让观察器工作,您必须实例化它。在我的示例中,我需要添加以下行:

Mongoid.observers = CommentBadgeObserver
Mongoid.instantiate_observers
在Rails中,您可以通过将其添加到config/application.rb中实现相同的功能(根据:

我认为CommentBadge中也有一个小的逻辑错误。请检查的条件,
>1
应该是
>0

最后,我更改了
User#award
方法以保存徽章而不是用户,因为存储关系的“外键”字段位于徽章一侧

class Comment
  include Mongoid::Document
  field :name
  belongs_to :user
end

class CommentBadgeObserver < Mongoid::Observer
  observe :comment

  def after_create(comment)
    CommentBadge.check_conditions_for(comment.user)
  end
end

class Badge
  include Mongoid::Document
  field :title
  belongs_to :user
end

class CommentBadge < Badge
  def self.check_conditions_for(user)
    if user.comments.size > 0
      badge = CommentBadge.create!(:title => "Comment badge")
      user.award(badge)
    end
  end
end

class User 
  include Mongoid::Document
  field :first_name
  has_many :comments
  has_many :badges

  def award(badge)
    self.badges << badge
    badge.save!
  end
end

Factory.define(:user) do |u|
  u.first_name 'Bob'
end

Factory.define(:comment) do |c|
  c.name 'Some comment...'
end

# Observers need to be instantiated
Mongoid.observers = CommentBadgeObserver
Mongoid.instantiate_observers

describe CommentBadgeObserver do
  it 'should create badges' do
    @user = Factory.build(:user)
    @comment = Factory(:comment, :user => @user)
    @user.badges.count.should == 1
    @user.badges[0].title.should == "Comment badge"
  end
end
类注释
include Mongoid::Document
字段:名称
属于:用户
结束
类CommentBadgeObserver0
badge=CommentBadge.create!(:title=>“评论徽章”)
用户奖励(徽章)
结束
结束
结束
类用户
include Mongoid::Document
字段:名字
有很多评论
你有很多徽章吗
def奖(徽章)
self.badges@user)
@user.badges.count.should==1
@user.badges[0]。title.should==“评论徽章”
结束
结束

很高兴认识你,谢谢你。您是否在Rails中使用了它,它是observer实例化还是其他什么?是的,我在我的应用程序中使用了它;我必须在我的规范文件中设置观察者实例化的两行。
Mongoid.observers = CommentBadgeObserver
Mongoid.instantiate_observers
config.mongoid.observers = :comment_badge_observer
class Comment
  include Mongoid::Document
  field :name
  belongs_to :user
end

class CommentBadgeObserver < Mongoid::Observer
  observe :comment

  def after_create(comment)
    CommentBadge.check_conditions_for(comment.user)
  end
end

class Badge
  include Mongoid::Document
  field :title
  belongs_to :user
end

class CommentBadge < Badge
  def self.check_conditions_for(user)
    if user.comments.size > 0
      badge = CommentBadge.create!(:title => "Comment badge")
      user.award(badge)
    end
  end
end

class User 
  include Mongoid::Document
  field :first_name
  has_many :comments
  has_many :badges

  def award(badge)
    self.badges << badge
    badge.save!
  end
end

Factory.define(:user) do |u|
  u.first_name 'Bob'
end

Factory.define(:comment) do |c|
  c.name 'Some comment...'
end

# Observers need to be instantiated
Mongoid.observers = CommentBadgeObserver
Mongoid.instantiate_observers

describe CommentBadgeObserver do
  it 'should create badges' do
    @user = Factory.build(:user)
    @comment = Factory(:comment, :user => @user)
    @user.badges.count.should == 1
    @user.badges[0].title.should == "Comment badge"
  end
end