I have two blocks of tests: one for testing positive outcomes and one for testing negative. After poking around, I''ve concluded that the underlying :verify_credentials method is getting called, despite the stub: describe ''electricity credentials'' do before(:each) do @wizard.electricity_service = MeteredService::Base.create!() end it ''with valid credentials should spawn external loader'' do @wizard.electricity_service.stub(:verify_credentials).and_return(true) @wizard.electricity_loader.stub(:start) @wizard.electricity_loader.should_receive(:start) @wizard.validate_setting_electricity_credentials end it ''with invalid credentials should not spawn external loader'' do @wizard.electricity_service.stub(:verify_credentials).and_raise(''no can do'') @wizard.electricity_loader.stub(:start) @wizard.electricity_loader.should_not_receive(:start) @wizard.validate_setting_electricity_credentials end end Am I missing something fundamental about .stub()? - ff -- Posted via http://www.ruby-forum.com/.
On Jan 12, 2012, at 5:32 PM, Fearless Fool wrote:> I have two blocks of tests: one for testing positive outcomes and one > for testing negative. After poking around, I''ve concluded that the > underlying :verify_credentials method is getting called, despite the > stub: > > describe ''electricity credentials'' do > before(:each) do > @wizard.electricity_service = MeteredService::Base.create!() > end > > it ''with valid credentials should spawn external loader'' do > @wizard.electricity_service.stub(:verify_credentials).and_return(true) > @wizard.electricity_loader.stub(:start) > @wizard.electricity_loader.should_receive(:start) > @wizard.validate_setting_electricity_credentials > end > > it ''with invalid credentials should not spawn external loader'' do > @wizard.electricity_service.stub(:verify_credentials).and_raise(''no > can do'') > @wizard.electricity_loader.stub(:start) > @wizard.electricity_loader.should_not_receive(:start) > @wizard.validate_setting_electricity_credentials > end > > end > > Am I missing something fundamental about .stub()? > > - ff > > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-usersWhat are the failed expectations? Just paste it. Are you sure that @wizard.electricity_service is returning the same object on each call? If a database call is being made, there''s a good chance it is returning a different object (which has not mocks).
Justin Ko wrote in post #1040632:> What are the failed expectations? Just paste it.You''ve identified the problem (see below), but to answer your question: 1) Wizard electricity credentials with valid credentials should spawn external loader Failure/Error: @wizard.electricity_loader.should_receive(:start) (#<Wizard::ElectricityLoader:0x000001029bc140>).start(any args) expected: 1 time received: 0 times # ./spec/models/wizard_spec.rb:181:in `block (4 levels) in <top (required)>''> Are you sure that @wizard.electricity_service is returning the same > object on each call? If a database call is being made, there''s a good > chance it is returning a different object (which has not mocks).Ah! I think that''s the culprit -- @wizard.electricity_service invokes a db call: class Wizard < ActiveRecord::Base def electricity_service premise.metered_services.where(:natural_resource_id => NaturalResource::ELECTRICITY.id) end end It seems obvious now that you point it out. So in rspec-land, what''s the stylistically appropriate way to test this? Stub .any_class()? -- Posted via http://www.ruby-forum.com/.
On 13 January 2012 05:18, Fearless Fool <lists at ruby-forum.com> wrote:> Justin Ko wrote in post #1040632: >> What are the failed expectations? Just paste it. > > You''ve identified the problem (see below), but to answer your question: > > ?1) Wizard electricity credentials with valid credentials should spawn > external loader > ? ? Failure/Error: @wizard.electricity_loader.should_receive(:start) > ? ? ? (#<Wizard::ElectricityLoader:0x000001029bc140>).start(any args) > ? ? ? ? ? expected: 1 time > ? ? ? ? ? received: 0 times > ? ? # ./spec/models/wizard_spec.rb:181:in `block (4 levels) in <top > (required)>'' > >> Are you sure that @wizard.electricity_service is returning the same >> object on each call? If a database call is being made, there''s a good >> chance it is returning a different object (which has not mocks). > > Ah! ?I think that''s the culprit -- @wizard.electricity_service invokes a > db call: > > class Wizard < ActiveRecord::Base > ?def electricity_service > ? ?premise.metered_services.where(:natural_resource_id => > NaturalResource::ELECTRICITY.id) > ?end > end >I think your tests are telling you to refactor your code. the `premise.metered_services.where` is breaking the law of demeter. This makes it hard to stub/mock. I''d also question the naming of the Wizard class. One thing to consider doing is running the tests with the pretty output and reading it. So why should Wizard#electricity_service spawn an external loader? Why should a Wizard have an electricity service etc. There ia a tendency when writing specs, to focus on getting the spec to pass, and doing complicated things to make this happen. But really its much more important to listen to the tests to make things clear and simple. In this case perhaps there is an ElectricityService class asking to be born. HTH Andrew> It seems obvious now that you point it out. ?So in rspec-land, what''s > the stylistically appropriate way to test this? ?Stub .any_class()? > > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users-- ------------------------ Andrew Premdas blog.andrew.premdas.org