2014-06-26 9 views
14

Mam klasę ReturnItem.Ruby + Rspec: Jak powinienem testować attr_accessor?

specyfikacje:

require 'spec_helper' 

describe ReturnItem do 
    #is this enough? 
    it { should respond_to :chosen } 
    it { should respond_to :chosen= } 

end 

klasy:

class ReturnItem 
    attr_accessor :chosen 
end 

Wydaje się nieco nudny ponieważ attr_accessor jest używany praktycznie w każdej klasie. Czy istnieje skrót do tego w rspec, aby przetestować domyślną funkcjonalność programu pobierającego i ustawiającego? Czy muszę przejść przez proces testowania gettera i setera indywidualnie i ręcznie dla każdego atrybutu?

+0

Można by pomyśleć, że jest to część podstawowych bibliotek Rspec/Shoulda, prawda? –

Odpowiedz

10

stworzyłem własny RSpec matcher dla tego:

spec/custom/matchers/should_have_attr_accessor.rb

RSpec::Matchers.define :have_attr_accessor do |field| 
    match do |object_instance| 
    object_instance.respond_to?(field) && 
     object_instance.respond_to?("#{field}=") 
    end 

    failure_message_for_should do |object_instance| 
    "expected attr_accessor for #{field} on #{object_instance}" 
    end 

    failure_message_for_should_not do |object_instance| 
    "expected attr_accessor for #{field} not to be defined on #{object_instance}" 
    end 

    description do 
    "checks to see if there is an attr accessor on the supplied object" 
    end 
end 

Wtedy w moim specyfikacji, używam go tak:

subject { described_class.new } 
it { should have_attr_accessor(:foo) } 
+0

Bardzo podoba mi się prostota twojego matchera. Czuję się o wiele bardziej komfortowo, dodając go do mojego kodu. Bardziej dokładny matcher, który również obsługuje 'attr_reader' i' attr_writer', rzuca okiem na https://gist.github.com/daronco/4133411#file-have_attr_accessor-rb –

9

Jest to zaktualizowana wersja poprzednia odpowiedź przy użyciu RSpec 3, zastępując failure_message_for_should dla failure_message i failure_message_for_should_not dla failure_message_when_negated:

RSpec::Matchers.define :have_attr_accessor do |field| 
    match do |object_instance| 
    object_instance.respond_to?(field) && 
     object_instance.respond_to?("#{field}=") 
    end 

    failure_message do |object_instance| 
    "expected attr_accessor for #{field} on #{object_instance}" 
    end 

    failure_message_when_negated do |object_instance| 
    "expected attr_accessor for #{field} not to be defined on #{object_instance}" 
    end 

    description do 
    "assert there is an attr_accessor of the given name on the supplied object" 
    end 
end