Daniel Salmeron Amselem
2010-May-14 15:09 UTC
[rspec-users] RSpec and Factory Girl: Destroying an object
Hi, I have a problem when testing the deletion of a record from the database. I am using RSpec methods to check if my account object is being destroyed. The factory creates an account object and saves it into the DB. Also the two should_receive expectations seem to work. The problem is that when checking the database after the "delete :destroy, :id => account" line, the account record still exists. it "should be able to destroy an account" do account = Factory(:account) Account.should_receive(:find).and_return(account) account.should_receive(:destroy) delete :destroy, :id => account Account.all.should == [] response.should be_success response.should render_template("new") end # app/controllers/accounts_controller.rb def destroy account = Account.find(params[:id]) account.destroy redirect_to accounts_path end I hope someone can help me on this one. Thanks
Pat Maddox
2010-May-14 15:27 UTC
[rspec-users] RSpec and Factory Girl: Destroying an object
On May 14, 2010, at 8:09 AM, Daniel Salmeron Amselem wrote:> Hi, > > I have a problem when testing the deletion of a record from the > database. I am using RSpec methods to check if my account object is > being destroyed. > > The factory creates an account object and saves it into the DB. Also > the two should_receive expectations seem to work. > > The problem is that when checking the database after the > "delete :destroy, :id => account" line, the account record still > exists. > > > it "should be able to destroy an account" do > account = Factory(:account) > Account.should_receive(:find).and_return(account) > account.should_receive(:destroy) > > delete :destroy, :id => account > > Account.all.should == [] > response.should be_success > response.should render_template("new") > end > > # app/controllers/accounts_controller.rb > def destroy > account = Account.find(params[:id]) > account.destroy > > redirect_to accounts_path > end > > I hope someone can help me on this one.You''ve mocked out the call to destroy, which hides the original implementation. Pick either a state-based test (checking the database, don''t use mocks) or mock-based test, but don''t mix and match. Pat
Daniel Salmeron Amselem
2010-May-14 20:11 UTC
[rspec-users] RSpec and Factory Girl: Destroying an object
Hey Pat, thanks for replying. How would you test this method? Checking the database or mocking? Is there any advantage of using one over the other ? I don''t really understand the benefits of using mocks, so could you tell me how would you write the test using both methods (mocking, and checking the DB? Could you explain me the advantages of using mocking and advantages of checking de DB? Thank you very much, Dani On May 14, 5:27?pm, Pat Maddox <mailingli... at patmaddox.com> wrote:> On May 14, 2010, at 8:09 AM, Daniel Salmeron Amselem wrote: > > > > > > > Hi, > > > I have a problem when testing the deletion of a record from the > > database. I am using RSpec methods to check if my account object is > > being destroyed. > > > The factory creates an account object and saves it into the DB. Also > > the two should_receive expectations seem to work. > > > The problem is that when checking the database after the > > "delete :destroy, :id => account" line, the account record still > > exists. > > > ? ?it "should be able to destroy an account" do > > ? ? ?account = Factory(:account) > > ? ? ?Account.should_receive(:find).and_return(account) > > ? ? ?account.should_receive(:destroy) > > > ? ? ?delete :destroy, :id => account > > > ? ? ?Account.all.should == [] > > ? ? ?response.should be_success > > ? ? ?response.should render_template("new") > > ? ?end > > > ?# app/controllers/accounts_controller.rb > > ?def destroy > > ? ?account = Account.find(params[:id]) > > ? ?account.destroy > > > ? ?redirect_to accounts_path > > ?end > > > I hope someone can help me on this one. > > You''ve mocked out the call to destroy, which hides the original implementation. ?Pick either a state-based test (checking the database, don''t use mocks) or mock-based test, but don''t mix and match. > > Pat > _______________________________________________ > rspec-users mailing list > rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users > > -- > You received this message because you are subscribed to the Google Groups "rspec" group. > To post to this group, send email to rspec at googlegroups.com. > To unsubscribe from this group, send email to rspec+unsubscribe at googlegroups.com. > For more options, visit this group athttp://groups.google.com/group/rspec?hl=en.
J. B. Rainsberger
2010-May-15 00:19 UTC
[rspec-users] RSpec and Factory Girl: Destroying an object
Daniel Salmeron Amselem wrote:> How would you test this method? Checking the database or mocking? Is > there any advantage of using one over the other ?Hi, Dani. You originally wrote that you want "to check if my account object is being destroyed." I can think of a few reasons to check this: 1. I don''t yet know Rails well and want to check that I understand how #destroy works. 2. I don''t trust Rails to destroy an object correctly. 3. I''ve configured some behavior of my object in a way that might cause Rails to destroy it differently than I expect. 4. I think I''ve found a bug in Rails. Do you want to check the destroy method for one of these reasons, or something else entirely? I ask, because that information guides me to choose one of three options: 1. Check #destroy by invoking it directly. 2. Check a client by stubbing/mocking #destroy. 3. Don''t check #destroy at all. Since I didn''t write #destroy, I prefer not to check it. (Principle: Don''t Test The Platform.) If I don''t trust #destroy, I check it by invoking it directly, because I think there might be a bug in Rails. If I don''t understand what #destroy does, I check it by invoking it directly, because I''m writing Learning Tests. (Principle: Write examples to check your assumptions about how someone else''s code works.)> I don''t really understand the benefits of using mocks, so could you > tell me how would you write the test using both methods (mocking, and > checking the DB? Could you explain me the advantages of using mocking > and advantages of checking de DB?I think of it this way: if I want to check #destroy, I invoke it directly with the database; but if I want to check that my code asks to destroy an object at the right time, I mock #destroy; and finally, if I want to check that my code reacts appropriately after destroying an object, then I stub #destroy. To understand some of the underlying principles, I humbly recommend this: http://jbrains.ca/integrated_tests_are_a_scam (The articles are in order from newest first, so start at the end). Enjoy. -- J. B. Rainsberger :: http://www.jbrains.ca :: http://www.thecodewhisperer.com