Patrick J. Collins
2012-May-04 20:07 UTC
[rspec-users] rspec 2.10.0 breaks controller specs...
Apparently 2.10.0 doesn''t like this line in devise''s lib/devise/test_helpers.rb @request.env[''warden''] = Warden::Proxy.new(@request.env, manager) ... This worked fine in 2.8.1, but now all my controller specs give me: Failure/Error: Unable to find matching line from backtrace NoMethodError: undefined method `env'' for nil:NilClass # /Users/patrick/.rvm/gems/ruby-1.9.3-p125 at my_app/gems/devise-2.0.4/lib/devise/test_helpers.rb:33:in `warden'' # /Users/patrick/.rvm/gems/ruby-1.9.3-p125 at my_app/gems/rspec-rails-2.10.0/lib/rspec/rails/adapters.rb:15:in `block (2 levels) in setup'' # /Users/patrick/.rvm/gems/ruby-1.9.3-p125 at my_app/gems/rspec-core-2.10.0/lib/rspec/core/example.rb:178:in `instance_eval'' # /Users/patrick/.rvm/gems/ruby-1.9.3-p125 at my_app/gems/rspec-core-2.10.0/lib/rspec/core/example.rb:178:in `instance_eval'' # /Users/patrick/.rvm/gems/ruby-1.9.3-p125 at my_app/gems/rspec-core-2.10.0/lib/rspec/core/hooks.rb:23:in `run'' # /Users/patrick/.rvm/gems/ruby-1.9.3-p125 at my_app/gems/rspec-core-2.10.0/lib/rspec/core/hooks.rb:63:in `block in run'' # /Users/patrick/.rvm/gems/ruby-1.9.3-p125 at my_app/gems/rspec-core-2.10.0/lib/rspec/core/hooks.rb:63:in `each'' # /Users/patrick/.rvm/gems/ruby-1.9.3-p125 at my_app/gems/rspec-core-2.10.0/lib/rspec/core/hooks.rb:63:in `run'' # /Users/patrick/.rvm/gems/ruby-1.9.3-p125 at my_app/gems/rspec-core-2.10.0/lib/rspec/core/hooks.rb:400:in `run_hook'' # /Users/patrick/.rvm/gems/ruby-1.9.3-p125 at my_app/gems/rspec-core-2.10.0/lib/rspec/core/example_group.rb:298:in `run_before_each_hooks'' # /Users/patrick/.rvm/gems/ruby-1.9.3-p125 at my_app/gems/rspec-core-2.10.0/lib/rspec/core/example.rb:239:in `run_before_each'' # /Users/patrick/.rvm/gems/ruby-1.9.3-p125 at my_app/gems/rspec-core-2.10.0/lib/rspec/core/example.rb:86:in `block in run'' # /Users/patrick/.rvm/gems/ruby-1.9.3-p125 at my_app/gems/rspec-core-2.10.0/lib/rspec/core/example.rb:195:in `with_around_each_hooks'' # /Users/patrick/.rvm/gems/ruby-1.9.3-p125 at my_app/gems/rspec-core-2.10.0/lib/rspec/core/example.rb:84:in `run'' # /Users/patrick/.rvm/gems/ruby-1.9.3-p125 at my_app/gems/rspec-core-2.10.0/lib/rspec/core/example_group.rb:353:in `block in run_examples'' # /Users/patrick/.rvm/gems/ruby-1.9.3-p125 at my_app/gems/rspec-core-2.10.0/lib/rspec/core/example_group.rb:349:in `map'' # /Users/patrick/.rvm/gems/ruby-1.9.3-p125 at my_app/gems/rspec-core-2.10.0/lib/rspec/core/example_group.rb:349:in `run_examples'' # /Users/patrick/.rvm/gems/ruby-1.9.3-p125 at my_app/gems/rspec-core-2.10.0/lib/rspec/core/example_group.rb:335:in `run'' # /Users/patrick/.rvm/gems/ruby-1.9.3-p125 at my_app/gems/rspec-core-2.10.0/lib/rspec/core/example_group.rb:336:in `block in run'' # /Users/patrick/.rvm/gems/ruby-1.9.3-p125 at my_app/gems/rspec-core-2.10.0/lib/r 17 def process(*) spec/core/example_group.rb:336:in `map'' # /Users/patrick/.rvm/gems/ruby-1.9.3-p125 at my_app/gems/rspec-core-2.10.0/lib/rspec/core/example_group.rb:336:in `run'' # /Users/patrick/.rvm/gems/ruby-1.9.3-p125 at my_app/gems/rspec-core-2.10.0/lib/rspec/core/command_line.rb:28:in `block (2 levels) in run'' # /Users/patrick/.rvm/gems/ruby-1.9.3-p125 at my_app/gems/rspec-core-2.10.0/lib/rspec/core/command_line.rb:28:in `map'' # /Users/patrick/.rvm/gems/ruby-1.9.3-p125 at my_app/gems/rspec-core-2.10.0/lib/rspec/core/command_line.rb:28:in `block in run'' # /Users/patrick/.rvm/gems/ruby-1.9.3-p125 at my_app/gems/rspec-core-2.10.0/lib/rspec/core/reporter.rb:34:in `report'' # /Users/patrick/.rvm/gems/ruby-1.9.3-p125 at my_app/gems/rspec-core-2.10.0/lib/rspec/core/command_line.rb:25:in `run'' # /Users/patrick/.rvm/gems/ruby-1.9.3-p125 at my_app/gems/rspec-core-2.10.0/lib/rspec/core/runner.rb:69:in `run'' # /Users/patrick/.rvm/gems/ruby-1.9.3-p125 at my_app/gems/rspec-core-2.10.0/lib/rspec/core/runner.rb:10:in `block in autorun'' Patrick J. Collins http://collinatorstudios.com
David Chelimsky
2012-May-04 20:10 UTC
[rspec-users] rspec 2.10.0 breaks controller specs...
On Fri, May 4, 2012 at 3:07 PM, Patrick J. Collins <patrick at collinatorstudios.com> wrote:> Apparently 2.10.0 doesn''t like this line in devise''s lib/devise/test_helpers.rb > ?@request.env[''warden''] = Warden::Proxy.new(@request.env, manager)Please file bug reports to https://github.com/rspec/rspec-rails/issues, and please look to see if someone else already has before you do: https://github.com/rspec/rspec-rails/issues/534 Cheers, David
Patrick J. Collins
2012-May-04 23:14 UTC
[rspec-users] Preferred way to predict behavior in controller spec?
So, I have an action like this: def destroy if purchase.user == current_user && purchase.refund redirect_to purchase else flash[:error] = t("purchases.refund.failure") render :show end end ... I wanted a controller test to verify the following: 1. It''s the correct user 2. The refund was successful 3. User is redirected ... Initially, I thought this would go something like this: describe "#destroy" do let(:purchase) { create_purchase } it "refunds the buyer" do subject.stubs(:current_user).returns purchase.user purchase.stubs(:refund).returns true put :destroy, { :id => purchase.id } response.should be_redirect end end WRONG!!!!!!!!! Obviously, that is not cool because purchase.stubs(:refund) will not be the right object in the context of the controller...... So since my controller is actually doing the following: def destroy if purchase.user # etc... end private def purchase @purchase ||= Purchase.find(params[:id]) end I could do: subject.stubs(:purchase).returns(purchase) .. However, now that kind of defeats the purpose of put :destroy, { :id => purchase.id }... So I didn''t really like that-- I am no longer verifying it''s the right record, so maybe the things I wanted to test were actually: 1. It finds the purchase 2. It''s the correct user 3. The refund was successful 4. User is redirected ........ So I ended up making my test do: describe "#destroy" do let(:purchase) { create_purchase } def do_destroy put :destroy, { :id => purchase.id } end it "refunds the buyer" do subject.stubs(:current_user).returns purchase.user Purchase.any_instance.stubs(:refund).returns true do_destroy response.should be_redirect end subject.stubs(:current_user).returns purchase.user Purchase.any_instance.stubs(:refund).returns true do_destroy response.should redirect_to purchase.offer end it "does not refund the buyer when it fails" do subject.stubs(:current_user).returns purchase.user Purchase.any_instance.stubs(:refund).returns false put :destroy, :id => purchase.id response.should_not be_redirect end it "does not refund the buyer when it''s the wrong user" do subject.stubs(:current_user).returns create_user Purchase.any_instance.expects(:refund).never do_destroy response.should_not be_redirect end end But then I heard the voice of an old friend in my head, saying (with a long trailing echo) "any_instance is terrible practice.. never use it!" So I am curious if anyone has suggestions on how this might be improved? Thank you. Patrick J. Collins http://collinatorstudios.com
Zach Dennis
2012-May-05 03:21 UTC
[rspec-users] Preferred way to predict behavior in controller spec?
On Fri, May 4, 2012 at 7:14 PM, Patrick J. Collins <patrick at collinatorstudios.com> wrote:> So, I have an action like this: > > ?def destroy > ? ?if purchase.user == current_user && purchase.refund > ? ? ?redirect_to purchase > ? ?else > ? ? ?flash[:error] = t("purchases.refund.failure") > ? ? ?render :show > ? ?end > ?end > > ... ?I wanted a controller test to verify the following: > > ?1. ?It''s the correct user > ?2. ?The refund was successful > ?3. ?User is redirected > > ... > > Initially, I thought this would go something like this: > > ?describe "#destroy" do > ? ?let(:purchase) { create_purchase } > > ? ?it "refunds the buyer" do > ? ? ?subject.stubs(:current_user).returns purchase.user > ? ? ?purchase.stubs(:refund).returns true > ? ? ?put :destroy, { :id => purchase.id } > ? ? ?response.should be_redirect > ? ?end > ?end > > WRONG!!!!!!!!! > > Obviously, that is not cool because purchase.stubs(:refund) will not be the > right object in the context of the controller...... ?So since my controller is actually doing the following: > > ?def destroy > ? ?if purchase.user # etc... > ?end > > ?private > > ?def purchase > ? ?@purchase ||= Purchase.find(params[:id]) > ?end > > I could do: > > subject.stubs(:purchase).returns(purchase) > > .. ?However, now that kind of defeats the purpose of put :destroy, { :id => purchase.id }...> > So I didn''t really like that-- I am no longer verifying it''s the right record, > so maybe the things I wanted to test were actually: > > ?1. ?It finds the purchase > ?2. ?It''s the correct user > ?3. ?The refund was successful > ?4. ?User is redirected > > ........ > > So I ended up making my test do: > > ?describe "#destroy" do > ? ?let(:purchase) { create_purchase } > > ? ?def do_destroy > ? ? ?put :destroy, { :id => purchase.id } > ? ?end > > ? ?it "refunds the buyer" do > ? ? ?subject.stubs(:current_user).returns purchase.user > ? ? ?Purchase.any_instance.stubs(:refund).returns true > ? ? ?do_destroy > ? ? ?response.should be_redirect > ? ?end > ? ? ?subject.stubs(:current_user).returns purchase.user > ? ? ?Purchase.any_instance.stubs(:refund).returns true > > ? ? ?do_destroy > ? ? ?response.should redirect_to purchase.offer > ? ?end > > ? ?it "does not refund the buyer when it fails" do > ? ? ?subject.stubs(:current_user).returns purchase.user > ? ? ?Purchase.any_instance.stubs(:refund).returns false > > ? ? ?put :destroy, :id => purchase.id > ? ? ?response.should_not be_redirect > ? ?end > > ? ?it "does not refund the buyer when it''s the wrong user" do > ? ? ?subject.stubs(:current_user).returns create_user > ? ? ?Purchase.any_instance.expects(:refund).never > > ? ? ?do_destroy > ? ? ?response.should_not be_redirect > ? ?end > ?end > > But then I heard the voice of an old friend in my head, saying (with a long > trailing echo) "any_instance is terrible practice.. never use it!" > > So I am curious if anyone has suggestions on how this might be improved?Instead of any_instance you could stub the interaction with Purchase.find in your spec: Purchase.stubs(:find).with(purchase.id).returns purchase HTH, Zach> > Thank you. > > Patrick J. Collins > http://collinatorstudios.com > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users-- -- @zachdennis http://www.continuousthinking.com http://www.mutuallyhuman.com