2012-12-15 15 views
14

Próbuję pobrać dowolne wystąpienie jakiejś klasy. Muszę zatkać metodę fetch, która wypełnia ja z pewnymi danymi.RSpec any_instance return self

Jak uzyskać dostęp do zmiennej self, zmodyfikować ją i wrócić na metodę fetch?

MyObject.any_instance.stub(:fetch) { self } 

nie zwraca instancji MyObject.

Być może, mocks są bardziej przydatne w tej sytuacji. Niestety, jeszcze ich nie zrozumiałem.

Odpowiedz

1

O ile widzę, nie wydaje się to możliwe z jakiegoś powodu. Sprawdziłem bieżącego rspec-mocks realizację, a metoda faktycznie powołując realizację skrótową wydaje się być następujące:

# lib/rspec/mocks/message_expectation.rb:450 
def call_implementation(*args, &block) 
    @implementation.arity == 0 ? @implementation.call(&block) : @implementation.call(*args, &block) 
end 

Jak się wydaje, blok jest po prostu wywołana przez siebie, a nie przez instance_eval. Może jest jeszcze inna technika, aby osiągnąć to, co chcesz, mimo wszystko nie jestem ekspertem RSpec w jakikolwiek sposób.

12

Istnieje open rspec-mocks issue, aby rozwiązać ten problem. Mam nadzieję, że w pewnym momencie uda mi się go rozwiązać, ale nie jest łatwo dodać to w sposób, który nie niszczy istniejących specyfikacji, które używają any_instance z implementacją blokową, ponieważ zaczęlibyśmy generować dodatkowy argument (np. Obiekt instancja).

Ogólnie rzecz biorąc, any_instance może się przydać w niektórych sytuacjach, ale jest trochę powonieniem, a generalnie będziesz mieć mniej problemów, jeśli znajdziesz sposób na udawanie lub odgadywanie poszczególnych instancji.

Oto pracę wokół, że nie testowałem, ale powinno działać:

orig_new = MyObject.method(:new) 
MyObject.stub(:new) do |*args, &block| 
    orig_new.call(*args, &block).tap do |instance| 
    instance.stub(:fetch) { instance } 
    end 
end 

Zasadniczo jesteśmy symulowanie any_instance tutaj przez zahaczenie do MyObject.new tak, że możemy skrótową fetch na każdy nowy przykład, że jest tworzony.

Wszystko, co powiedzieliśmy, jest ważne, aby "słuchać twoich testów", a gdy coś jest trudne do sprawdzenia, rozważ to, co mówi o twoim projekcie, zamiast natychmiast korzystać z narzędzi elektrycznych, takich jak any_instance. Twoje pierwotne pytanie nie daje mi wystarczającego kontekstu, aby spekulować cokolwiek na temat twojego projektu, ale zdecydowanie jest to miejsce, od którego zacznę w obliczu konieczności zrobienia tego.

+0

Pracowałem dla mnie dobrze! Wielkie dzięki! – jethroo