2010-10-20 13 views
6

ben böyle bir şey yapmak:Rspec örneklerini ekleyen yöntemleri nasıl yazarım? RSpec raylar birim özelliklerinin bir demet olarak

describe Foo do 
    spec_has_many Foo, :bar, :baz 
end 

Peki nasıl spec_has_many() gibi bir yardımcı yöntem yazıyorum: Daha doğrusu böyle bir şey yapmak istiyorum temizleyici kodu için

describe Foo do 
    [:bar, :baz].each do |a| 
    it "should have many #{a}" do 
     Foo.should have_many(a) 
    end 
    end 
end 

rspec'in it() yöntemi gibi DSL kodunu eklemek için? RSpec örneklerini tanımlamak için eşdeğer ne olurdu

def spec_has_many(model, *args) 
    args.each do |a| 
    define_method("it_should_have_many_#{a}") do 
     model.should have_many(a) 
    end 
    end 
end 

: sıradan bir örnek yöntemi için olsaydı ben böyle bir şey yapar?

cevap

9

Tamam, bu biraz uğraşıyordu, ama sanırım çalışıyorum. Bu metaprogramming hackery bir parçasıdır ve ben şahsen sadece açıklanan ilk şeyi kullanmak istiyorsunuz, ama sen öyle istiyorsun: P Foo bir has_many? yöntemi olmadığı için

module ExampleMacros 
    def self.included(base) 
    base.extend(ClassMethods) 
    end 

    module ClassMethods 
    # This will be available as a "Class Macro" in the included class 
    def should_have_many(*args) 
     args.each do |a| 
     # Runs the 'it' block in the context of the current instance 
     instance_eval do 
      # This is just normal RSpec code at this point 
      it "should have_many #{a.to_s}" do 
      subject.should have_many(a) 
      end 
     end 
     end 
    end 
    end 
end 

describe Foo do 
    # Include the module which will define the should_have_many method 
    # Can be done automatically in RSpec configuration (see below) 
    include ExampleMacros 

    # This may or may not be required, but the should_have_many method expects 
    # subject to be defined (which it is by default, but this just makes sure 
    # it's what we expect) 
    subject { Foo } 

    # And off we go. Note that you don't need to pass it a model 
    should_have_many :a, :b 
end 

Benim gözlük başarısız, ancak her iki testler çalıştırmak , bu yüzden çalışması gerekir.

spec_helper.rb dosyanızdaki ExampleMacros modülünü tanımlayabilir ve yeniden adlandırabilirsiniz. bloklarınıza include ExampleMacros numaralı telefonu aramak istiyorsunuz (başkaları değil).

senin gözlük tüm otomatik modülü dahil olmak için, şöyle RSpec yapılandırın:

# RSpec 2.0.0 
RSpec.configure do |c| 
    c.include ExampleMacros 
end