On Fri, May 4, 2012 at 7:14 PM, Patrick J. Collins <patr...@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@rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users -- -- @zachdennis http://www.continuousthinking.com http://www.mutuallyhuman.com _______________________________________________ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users