سؤال

افترض أن لديك ActiveRecord::المراقب في أحد روبي على القضبان التطبيقات - كيف يمكنك اختبار هذا المراقب مع rSpec?

هل كانت مفيدة؟

المحلول

أنت على الطريق الصحيح ولكن يجب تشغيل في عدد من المحبط غير متوقعة رسالة أخطاء عند استخدام rSpec والمراقبين كائنات وهمية.وأنا عندما المواصفات اختبار نموذج بلدي أنا لا أريد أن يكون التعامل مع مراقب السلوك في رسالتي التوقعات.

في المثال الخاص بك, ليس هناك وسيلة جيدة المواصفات "set_status" على نموذج من دون معرفة ما المراقب هو ذاهب الى القيام به.

ولذلك أود أن استخدام "لا يحدقون" البرنامج المساعد. إعطاء التعليمات البرمجية أعلاه باستخدام أي مختلس النظر توم المساعد, وأود أن المواصفات نموذج مثل هذا:

describe Person do 
  it "should set status correctly" do 
    @p = Person.new(:status => "foo")
    @p.set_status("bar")
    @p.save
    @p.status.should eql("bar")
  end
end

يمكنك المواصفات الخاصة بك في نموذج التعليمات البرمجية دون الحاجة إلى القلق أن هناك مراقب هناك التي سوف تأتي في وهزم القيمة الخاصة بك.كنت المواصفات التي منفصل في person_observer_spec مثل هذا:

describe PersonObserver do
  it "should clobber the status field" do 
    @p = mock_model(Person, :status => "foo")
    @obs = PersonObserver.instance
    @p.should_receive(:set_status).with("aha!")
    @obs.after_save
  end
end 

إذا كنت حقا تريد حقا لاختبار إلى جانب نموذج و مراقب الصف ، يمكنك أن تفعل ذلك من هذا القبيل:

describe Person do 
  it "should register a status change with the person observer turned on" do
    Person.with_observers(:person_observer) do
      lambda { @p = Person.new; @p.save }.should change(@p, :status).to("aha!)
    end
  end
end

99% من الوقت, افضل مواصفات الاختبار مع المراقبين إيقاف.انها مجرد أسهل بهذه الطريقة.

نصائح أخرى

تنويه:لم فعلت هذا الواقع على إنتاج الموقع, ولكن يبدو معقولا طريقة استخدام كائنات وهمية, should_receive و الأصدقاء و أساليب الاحتجاج على المراقب مباشرة

وفيما يلي نموذج المراقب:

class Person < ActiveRecord::Base
  def set_status( new_status )
    # do whatever
  end
end

class PersonObserver < ActiveRecord::Observer
  def after_save(person)
    person.set_status("aha!")
  end
end

أود أن أكتب المواصفات مثل هذا (جريت عليه, وأنه يمر)

describe PersonObserver do
  before :each do
    @person = stub_model(Person)
    @observer = PersonObserver.instance
  end

  it "should invoke after_save on the observed object" do
    @person.should_receive(:set_status).with("aha!")
    @observer.after_save(@person)
  end
end

no_peeping_toms الآن جوهرة ويمكن العثور عليها هنا: https://github.com/patmaddox/no-peeping-toms

إذا كنت ترغب في اختبار أن يلاحظ المراقب النموذج الصحيح و يتلقى إخطار كما هو متوقع ، وهنا مثال على استخدام RR.

your_model.rb:

class YourModel < ActiveRecord::Base
    ...
end

your_model_observer.rb:

class YourModelObserver < ActiveRecord::Observer
    def after_create
        ...
    end

    def custom_notification
        ...
    end
end

your_model_observer_spec.rb:

before do
    @observer = YourModelObserver.instance
    @model = YourModel.new
end

it "acts on the after_create notification"
    mock(@observer).after_create(@model)
    @model.save!
end

it "acts on the custom notification"
    mock(@observer).custom_notification(@model)
    @model.send(:notify, :custom_notification)
end
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top