2012-06-01 14 views
32

Czy istnieje jakakolwiek metoda usuwania wszelkich skrótów i kpiny podczas korzystania z RSpec?W RSpec, czy istnieje metoda równoważna "unstub", ale "should_receive"?

Przykład:

RestClient.should_receive(:delete).with("http://www.example.com") 
... 
... 

# this will remove the mocking of "should_receive" and 
# restore the proper "delete" method on "RestClient". 
RestClient.mocking_reset 

(mocking_reset jest mój ficticious nazwę dla wymagać funkcjonalności).

Wiem, że istnieje metoda "unstub", która resetuje "stubs", ale nie "should_receive".

Czy istnieje odpowiednik metody "anuluj", ale "sprawdź"?

Panayotis

+0

To niedorzeczne, że nie można edytować mniej niż 6 znaków! Nazwa twojej metody mówi "mocking_resest" i powinna brzmieć 'mocking_reset'. –

+0

Dodaj wiadomość do edycji, a twoja edycja przekroczy 6 znaków :) – Galen

Odpowiedz

29

Obecnie (rspec-mocks 2.10.1) nie jest metoda odpowiednik do unstub ale should_receive. Możesz zresetować wszystkie kody pośredniczące i makiety za pomocą rspec_reset, a także możesz pisać brudne hacki, aby usunąć określone oczekiwania (których nie polecam).

Poniżej jest przykład usuwając wszystkie odcinki i oczekiwania na obiekcie:

describe "resetting stubs and expectations with rspec_reset" do 
    before do 
    @person = mock('person') 
    @person.should_receive(:poke) 
    end 

    it "should not fail when we reset all stubs and expectations" do 
    @person.rspec_reset 
    end 
end 

Należy zauważyć, że metoda ta jest odnotowany w kodzie źródłowym rspec jako @private, co oznacza, że ​​nie należy go używać więcej niż absolutnie konieczne i może przerwać w przyszłych wersjach rspec bez ostrzeżenia. Jest on jednak dość szeroko stosowany w specyfikacji dla samego rspec, więc wydaje się mniej prawdopodobne, że w najbliższym czasie sytuacja ta zostanie zahamowana.

Po wykopaniu przez kod rspec-drwi nieco więcej, można oczywiście zrobić coś naprawdę paskudnego i wyrwać jeden specyficzny oczekiwanie siebie:

# Works in rspec 2.10.1 
describe "removing an expectation with an ugly hack" do 
    before do 
    @person = mock('person') 
    @person.should_receive(:poke) 
    end 

    it "should not fail after we hack rspec by violating every law of good programming, ever" do 
    @person.instance_variable_get(:@mock_proxy).instance_variable_get(:@method_double)[:poke].clear 
    end 
end 

To jest naprawdę źle, ponieważ narusza hermetyzację pakiet testowy rspec i nie powinieneś tego robić. Zamiast tego, jeśli naprawdę miałeś nieodparty powód do usunięcia określonych oczekiwań, dobrym pomysłem byłoby dodanie do upublicznienia metody publicznej metody dodawania metody równoległej do unstub, ale w celu usunięcia określonych oczekiwań. Prawdopodobnie byłoby znaleźć tutaj (uwaga definicję stub i unstub jak dobrze w tym pliku):

https://github.com/rspec/rspec-mocks/blob/master/lib/rspec/mocks/methods.rb

Przed wyjściem i za pomocą dowolnego z sugestiami powyżej do usuwania oczekiwanie może warto rozważyć, czy Twoje specyfikacje naprawdę muszą to zrobić lub jeśli powinny być refaktoryzowane. Używanie should_receive jest zapewnieniem o kodzie i zazwyczaj powinieneś próbować tworzyć przykłady (tj. it bloków), które tylko potwierdzają jedną rzecz. Byłbym bardzo ciekawy, dlaczego potrzebujesz czegoś takiego, jak rspec_reset, chyba że próbujesz zrobić zbyt wiele w konfiguracji globalnej (np. before :each lub wcześniej: wszystkie bloki), lub jeśli twoje przykłady próbują zrobić zbyt wiele (np. wiele asercji w jednym przykładzie).

Jedynym wyjątkiem może być zestaw testów rspec-mocks, gdzie rspec_reset służy do resetowania stanu między przykładami testującymi funkcjonalność stosowania stubów i mocków. Jeśli tego nie robisz, istnieje duże prawdopodobieństwo, że twoje testy mogą zostać ulepszone, aby nie polegać na globalnych resetach stubów i mocków na obiekcie.

Mam nadzieję, że to pomoże i proszę dać mi znać, jeśli uważasz, że istnieje uzasadniony przypadek dodania równoważnej metody do unstub, ale w przypadku oczekiwań dotyczących wiadomości (tj. Po użyciu should_receive). Jeśli jestem przekonany, że to jest w porządku, rozważyłbym dodanie tej metody i zaproponowanie jej dodania wcześniej. Może to nazwać unset_expectation? Proszę również skorzystać z przewodnika w kodzie i wewnętrznych strukturach powyżej, aby samodzielnie utworzyć żądanie pobrania dla rspec-mocks, a zobaczymy, czy zostanie zaakceptowany, aby stworzyć kpinę równoważną unstub.

+1

Bardzo dziękuję za odpowiedź. Powodem, dla którego chciałem tej funkcjonalności, było to, że wykonałem metodę "clean_test_data" wykonaną "after: each". Wymagało to użycia prawdziwych metod. Po opublikowaniu mojego pytania na temat SOF, zdałem sobie sprawę, że nadal mogę użyć "clean_test_data", ale na "before: each" i to było rozwiązanie mojego problemu. W ten sposób nie potrzebowałem w końcu niczego rozpakować ani odblokować. W międzyczasie, odkąd znalazłem w przeszłości dobre powody, aby użyć "unstub", nie rozumiem, dlaczego nie mam odpowiednika "unset_expectation" ze względu na kompletność, a następnie niech decyduje użytkownik próbujący. –

6

Dla RSpec> = 2,14, zaakceptowana odpowiedź nie będzie działać. Odsyłam do odpowiedzi Bernhard Köhler na tym wątku (przedstawionym poniżej w celu ochrony przed martwy link): undefined method `rspec_reset' with rspec version 2.14

Metoda resetu nie istnieje w RSpec 2.14. Zamiast tego jest to metoda pomocnicza zdefiniowana w pliku spec_helper.rb dla projektu rspec-mocks .

module VerifyAndResetHelpers 
    def verify(object) 
    RSpec::Mocks.proxy_for(object).verify 
    end 

    def reset(object) 
    RSpec::Mocks.proxy_for(object).reset 
    end 
end 

Widać, że ta metoda delegaci akcja przywrócona bazowego proxy zamiast sklejaniu ją do definicji klasy danego przedmiotu.

31

Można nadpisać jakiś poprzedni wyśmianie przez:

expect(RestClient).to receive(:delete).and_call_original 

A jeśli to nie było żadnego rodzaju oczekiwania, tylko prosty en:

allow(RestClient).to receive(:delete).and_call_original 

Pamiętaj istnieje również expect_any_instance_of i allow_any_instance_of.

Powiązane problemy