Bugs: Browse | Submit New | Admin
I am having a problem where stubbing find on a has_many association doesn't appear to work. I don't know why and exactly what circumstances this occurs under, but I've made a test case for it. I know fixtures are evil but it requires a test database ;) (well maybe not but it's the easiest way to prove the problem for now as I don't actually know what causes it)
Add A Comment:
Date: 2009-01-02 16:43 Sender: James Mead This bug report has moved to Lighthouse [1]. [1] http://floehopper.lighthouseapp.com/projects/22289/tickets/16
Date: 2008-01-03 10:10 Sender: Jonathan Leighton Hi James, No problem, thanks for taking the time to look at it. Jon
Date: 2008-01-03 09:23 Sender: James Mead Hi Jonathan, My response was obviously a bit too speedy - I'm afraid I'd only looked at the failing test. BTW I really appreciate you taking the time to create failing tests for the bug report - they really help communication - especially if I were to read them properly! Anyway, now that I understand the problem a bit better, I'll have a bit more of a think. One reason I haven't done anything about this previously is that there is a workaround which isn't too ugly and I'd like to avoid any Rails-specific code creeping into Mocha. If it's not possible to come up with a generic solution, it might be worth splitting the Mocha Rails plugin out into a separate project and adding the Rails-specific code in that. Cheers, James. http://blog.floehopper.org
Date: 2008-01-02 23:38 Sender: Jonathan Leighton Hi James, Thanks for your speedy response. I figured it was probably something to do with AR's magic getting in the way. Stubbing the association proxy definitely does solve the problem (one of the tests I wrote shows this) but it would be lovely if that wasn't necessary :) Cheers, Jon
Date: 2008-01-02 23:24 Sender: James Mead I haven't yet had a chance to run the tests you attached, but I think there have always been problems trying to stub directly on the ActiveRecord association proxies - they aren't normal objects. The simplest solution is to stub the proxy method generated by the association - in this case House#rooms to replace the proxy object itself. Using the recently added block initializer code in Mocha, your first test could be something like this... def test_find_stubbed_on_the_association_should_work test_result = run_test do house, room = House.new, Room.new rooms = stub { stubs(:find).with(6).returns(room) } house.stubs(:rooms).returns(rooms) assert_equal room, house.rooms.find(6) end assert_passed(test_result) end Again, I'm sorry but I haven't tested this thoroughly. Let me know if this doesn't solve your problem. Cheers, James. http://blog.floehopper.org
Date: 2008-01-02 19:53 Sender: Jonathan Leighton This is the output from running the test: $ ruby test/acceptance/rails_has_many_find_acceptance_test.rb Loaded suite test/acceptance/rails_has_many_find_acceptance_test Started F.. Finished in 0.032379 seconds. 1) Failure: test_find_stubbed_on_the_association_should_work(RailsHasManyFind AcceptanceTest) [/home/turnip/Projects/mocha/test/test_runner.rb:24:in `assert_passed' test/acceptance/rails_has_many_find_acceptance_test.rb:29:in `test_find_stubbed_on_the_association_should_work' /home/turnip/Projects/mocha/lib/mocha/test_case_adapter.rb:19:in `__send__' /home/turnip/Projects/mocha/lib/mocha/test_case_adapter.rb:19:in `run']: Test failed unexpectedly with message: Error: test_me(): ActiveRecord::RecordNotFound: Couldn't find Room with ID=6 AND (rooms.house_id = NULL) /usr/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/ base.rb:1267:in `find_one' /usr/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/ base.rb:1250:in `find_from_ids' /usr/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/ base.rb:504:in `find' /usr/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/ associations/has_many_association.rb:66:in `find' test/acceptance/rails_has_many_find_acceptance_test.rb:27:in `test_me' /home/turnip/Projects/mocha/lib/mocha/test_case_adapter.rb:19:in `__send__' /home/turnip/Projects/mocha/lib/mocha/test_case_adapter.rb:19:in `run' /home/turnip/Projects/mocha/test/test_runner.rb:15:in `run_test' test/acceptance/rails_has_many_find_acceptance_test.rb:24:in `test_find_stubbed_on_the_association_should_work' /home/turnip/Projects/mocha/lib/mocha/test_case_adapter.rb:19:in `__send__' /home/turnip/Projects/mocha/lib/mocha/test_case_adapter.rb:19:in `run'. 3 tests, 1 assertions, 1 failures, 0 errors Of course ActiveRecord::Base#find should actually be called because the method is stubbed out...