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