Как я могу заглушить do_something
в rspec, до того, как вызывается первоначальная реализация (таким образом, от 42 до @x
)? И, конечно, без изменения реализации.rspec: Как заглушить метод экземпляра, вызываемый конструктором?
ответ
Here's the commit which adds the feature to rspec - Это было 25 мая 2008. При этом вы можете сделать
A.any_instance.stub(do_something: 23)
Однако последняя жемчужина v В версии rspec (1.1.11, октябрь 2008 г.) этот патч отсутствует.
This ticket заявляет, что они выдернули его по соображениям технического обслуживания, и альтернативное решение еще не было предоставлено.
Не похоже, что вы можете это сделать в этот момент. Вам придется вручную взломать класс, используя alias_method или somesuch.
Я не знаю, как сделать это в ложном рамках SPEC, но вы можете легко поменять его на мокко сделать следующее:
# should probably be in spec/spec_helper.rb
Spec::Runner.configure do |config|
config.mock_with :mocha
end
describe A, " when initialized" do
it "should set x to 42" do
A.new.x.should == 42
end
end
describe A, " when do_something is mocked" do
it "should set x to 23" do
A.any_instance.expects(:do_something).returns(23)
A.new.x.should == 23
end
end
или RR:
stub.any_instance_of(A).do_something { 23 }
В моей версии RSpec (1.2.2) я могу это сделать:
A.should_receive(:new).and_return(42)
Я знаю, что это, вероятно, до конца ответить на оригинальный плакат, но я ответить на него в любом случае для дальнейшего использования, а Я пришел сюда с тем же вопросом, но выяснил, что он работал над последней версией rspec.
тупикового метода экземпляра, вы можете сделать что-то вроде этого:
before :each do
@my_stub = stub("A")
@my_stub.should_receive(:do_something).with(no_args()).and_return(42)
@my_stub.should_receive(:do_something_else).with(any_args()).and_return(true)
A.stub(:new).and_return(my_stub)
end
Но pschneider указал, просто вернуться 42 на новом с: A.stub(:new).and_return(42)
или что-то в этом роде.
Я нашел это решение на http://pivotallabs.com/introducing-rr/
new_method = A.method(:new)
A.stub!(:new).and_return do |*args|
a = new_method.call(*args)
a.should_receive(:do_something).and_return(23)
a
end
я делаю, как Денис Barushev ответ. И я хотел бы предложить только одно косметическое изменение, которое делает ненужным переменную new_method
. Rspec делает munge на погасил методов, так что они могут быть доступны с proxied_by_rspec__
префиксом:
A.stub!(:new).and_return do |*args|
a = A.proxied_by_rspec__new(*args)
a.should_receive(:do_something).and_return(23)
a
end
Вот идея, которая может быть не очень элегантно, но в основном уверен работать:
Создать крохотный класс, наследует класс вы хотите проверить, переопределить метод инициализации и вызвать super
после создав заглушки в Initialize, например, так:
it "should call during_init in initialize" do
class TestClass < TheClassToTest
def initialize
should_receive(:during_init)
super
end
end
TestClass.new
end
и года u go! Я просто использовал это успешно в одном из моих тестов.
Драгоценный камень rspec_candy поставляется с вспомогательным методом stub_any_instance
, который работает как в RSpec 1, так и RSpec 2.
В RSpec 2.6 или более поздней версии вы можете использовать
A.any_instance.stub(do_something: 23)
См the docs для более подробной информации. (Спасибо rogerdpack за указание на то, что это теперь возможно - я думал, что он заслуживает ответа на свой собственный)
В последней версии RSpec на сегодня - 3.5 вы можете:
allow_any_instance_of(Widget).to receive(:name).and_return("Wibble")
кажется, что это был возвращен с 2.6.0, так что он сейчас там ... – rogerdpack 2011-08-26 17:02:27
@rogerdpack: действительно, наконец! http://blog.davidchelimsky.net/2011/05/12/rspec-260-is-released/ «Добавить поддержку any_instance.stub и any_instance.should_receive» – tokland 2011-09-08 20:22:25
Любая идея, если вы хотите прикрепить что-то непосредственно к этому экземпляру, созданному но новым? вроде should_receive (: blah) .exactlY (5) .times --- и вы не хотите, чтобы для какого-либо объекта, только этого конкретно? – xaxxon 2013-08-05 17:57:08