2013-04-21 17 views
5

Próbuję utworzyć niestandardowy matcher dla moich testów w RoR przy użyciu RSpec.RSpec & Custom matcher z wieloma argumentami

define :be_accessible do |attributes| 
    attributes = attributes.is_a?(Array) ? attributes : [attributes] 
    attributes.each do |attribute| 
     match do |response| 
     response.class.accessible_attributes.include?(attribute) 
     end 
     description { "#{attribute} should be accessible" } 
     failure_message_for_should { "#{attribute} should be accessible" } 
     failure_message_for_should_not { "#{attribute} should not be accessible" } 
    end 
    end 

Chciałbym móc napisać coś jak następuje w moich testów:

... 
should be_accessible(:name, :surname, :description) 
... 

ale z dopasowującego zdefiniowanego powyżej, I musi przekazać tablicę symboli zamiast symboli rozdzielonych przecinki w przeciwnym razie test bada tylko pierwszy symbol.

Wszelkie pomysły?

+0

Oto odpowiedź, która powinna pasować do pierwszej potrzeby: http://stackoverflow.com/a/4643289/582863. W każdym razie, jestem ciekawa twojej intencji tutaj ... Czy chcesz tylko zmniejszyć liczbę linii w plikach testowych rspec, czy też twój kompleks testowy ma dostęp do atrybutów modelu? – Saaman

+0

Problem z podanym linkiem polega na tym, że nie jest to "zwykła" metoda def, więc nie mogę użyć znaku *. Odpowiadając na twoje pytanie, chcę tylko zmniejszyć linie mojego rspec :) –

Odpowiedz

4

Zrobiłem to działa w ten sposób:

RSpec::Matchers.define :be_accessible do |*attributes| 
    match do |response| 

    description { "#{attributes.inspect} be accessible" } 

    attributes.each do |attribute| 
     failure_message_for_should { "#{attribute} should be accessible" } 
     failure_message_for_should_not { "#{attribute} should not be accessible" } 

     break false unless response.class.accessible_attributes.include?(attribute) 
    end 
    end 
end 

I odwrócony match a pętla each. Myślę, że tak właśnie oczekuje Rspec, ponieważ blok dany dla metody match jest taki, jaki został wykonany przez Rspec abstract matcher (jak sądzę).

Definiując blok za pomocą |*attributes|, pobiera listę parametrów i przekształca go w Array.

Zadzwonić pod numer should be_accessible(:name, :surname, :description).

Nawiasem mówiąc, jeśli po prostu chcesz sprawdzić istnienie cech, prosty

should respond_to(:name, :surname, :description) 

działa tak samo. Ale nie wygląda to na aspekt przypisywania mas.

+0

To działa, thanx na twój czas! Chcę sprawdzić przypisanie masy, więc twoje rozwiązanie jest tym, czego potrzebuję. –

+0

To naprawdę mi pomogło, ale kiedy zaadaptowałem ten przykład do mojej własnej sytuacji, okazało się, że działa tylko dla pozytywnych oczekiwań (nie działa dla should_not as-is). Musiałem stworzyć osobne bloki 'match_for_should' i' match_for_should_not', takie jak tutaj: https://www.relishapp.com/rspec/rspec-expectations/v/3-0/docs/custom-matchers/define-matcher#matcher -z oddzielną-logiką-za-należy-i-niech-nie – manafire

Powiązane problemy