2011-11-22 2 views
8

많은 의견이있는 사용자와 간단한 몽고 이드 데이터 모델에서 최소한 1 개의 주석을 쓸 때 특정 배지를 사용자에게 부여하고 싶습니다.rspec을 사용하여 Mongoid :: Observer를 테스트하는 방법

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 

user.award 방법 : (?하지만 관찰자가 백그라운드에서 실행되기 때문에 정상 추측)

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

다음 테스트가 실패

그래서 나는이 같은 관찰자를 설정

이 동작을 확인하는 가장 좋은 방법은 무엇입니까?

답변

7

나는 독자적으로 코드를 독자적으로 수정했다 (아래 참조). 당신이 기대했던대로 작동하도록 3 가지 작은 변화를 만들어야했습니다.

Observer를 작동 시키려면 인스턴스화해야합니다. 합니다 (docs에 따라) 레일에서

Mongoid.observers = CommentBadgeObserver 
Mongoid.instantiate_observers 

당신이 설정/application.rb이 추가 같은 일을 달성 할 수있다 : 내 예제에서 나는 줄을 추가하는 데 필요한

config.mongoid.observers = :comment_badge_observer 

내가이 생각 CommentBadge.check_conditions_for의 작은 논리 오류 인 경우 > 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 
+0

위대한 작품입니다! 스티브, 고마워! – obo

+0

잘 알고 감사드립니다. 레일즈에서 작업을하고 관찰자 인스턴스화 또는 다른 것입니까? – Steve

+0

네, 제 신청서에서 일 했어요. 옵저버 인스턴스화의 두 줄을 스펙 파일에 설정해야했습니다. – obo

관련 문제