Frodo Larik
2005-Dec-22 10:43 UTC
How to write unit tests with respect to model callbacks?
Hello, I am exploring the "Testing" part of Rails, but It seems some things work differently than I thought it would. Consider the following model: class Client < ActiveRecord::Base has_one :project def after_create Project.new(:name => self.name, :is_client => true, :client_id => self.id).save end def after_update self.project.update_attributes(:name => self.name, :disabled => self.disabled) end def before_destroy self.project.destroy end end and the following test: require File.dirname(__FILE__) + '/../test_helper' class ClientTest < Test::Unit::TestCase fixtures :clients def setup @client = Client.find(1) end def test_create assert_kind_of Client, @client assert_equal 1, @client.id assert_equal clients(:elasto_client).name, @client.name end def test_update assert_equal clients(:elasto_client).description, @client.description @client.description = "TEST UPDATE DESCRIPTION" assert @client.save, @client.errors.full_messages.join("; ") @client.reload assert_equal "TEST UPDATE DESCRIPTION", @client.description end def test_destroy @client.destroy assert_raise(ActiveRecord::RecordNotFound) { Client.find(@client.id) } end end larik@somehost $ ruby test/unit/client_test.rb Loaded suite test/unit/client_test Started .EE Finished in 0.577375 seconds. 1) Error: test_destroy(ClientTest): NoMethodError: You have a nil object when you didn't expect it! You might have expected an instance of ActiveRecord::Base. The error occured while evaluating nil.destroy /Users/larik/cvs/correlator/app/models/client.rb:46:in `before_destroy' /usr/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/active_record/callbacks.rb:348:in `send' /usr/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/active_record/callbacks.rb:348:in `callback' /usr/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/active_record/callbacks.rb:320:in `destroy_without_transactions' /usr/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/active_record/transactions.rb:122:in `destroy' /usr/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/active_record/transactions.rb:122:in `transaction' /usr/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/active_record/transactions.rb:91:in `transaction' /usr/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/active_record/transactions.rb:118:in `transaction' /usr/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/active_record/transactions.rb:122:in `destroy' test/unit/client_test.rb:25:in `test_destroy' 2) Error: test_update(ClientTest): NoMethodError: You have a nil object when you didn't expect it! You might have expected an instance of ActiveRecord::Base. The error occured while evaluating nil.update_attributes /Users/larik/cvs/correlator/app/models/client.rb:42:in `after_update' /usr/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/active_record/callbacks.rb:348:in `send' /usr/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/active_record/callbacks.rb:348:in `callback' /usr/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/active_record/callbacks.rb:275:in `update_without_timestamps' /usr/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/active_record/timestamp.rb:39:in `update' /usr/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/active_record/base.rb:1431:in `create_or_update_without_callbacks' /usr/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/active_record/callbacks.rb:249:in `create_or_update' /usr/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/active_record/base.rb:1226:in `save_without_validation' /usr/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/active_record/validations.rb:698:in `save_without_transactions' /usr/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/active_record/transactions.rb:126:in `save' /usr/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/active_record/transactions.rb:126:in `transaction' /usr/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/active_record/transactions.rb:91:in `transaction' /usr/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/active_record/transactions.rb:118:in `transaction' /usr/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/active_record/transactions.rb:126:in `save' test/unit/client_test.rb:19:in `test_update' 3 tests, 4 assertions, 0 failures, 2 errors It seems like the data for the clients is directly loaded from the fixtures files, it doesn't respect the callbacks defined in the model. E.g. creating of the Project data. My question is, what is the best way of getting "proper" data in the database, with respect to the fixtures data and the callbacks defined in the model. -- Sincerely, Frodo Larik _______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails
Francois Beausoleil
2005-Dec-22 12:32 UTC
Re: How to write unit tests with respect to model callbacks?
Hi ! 2005/12/22, Frodo Larik <frodolarik@gmail.com>:> It seems like the data for the clients is directly loaded from the > fixtures files, it doesn't respect the callbacks defined in the model. > E.g. creating of the Project data. > > My question is, what is the best way of getting "proper" data in the > database, with respect to the fixtures data and the callbacks defined > in the model.Yes, fixtures data is copied from the fixtures file to the DB, sans transformation. If you want the callbacks to execute, you'll have to create the data yourself, using ActiveRecord instances. On the other hand, fixtures are made to be loaded quickly and efficiently in the DB. So, just add a project to the projects.yml file, and in the fixtures line of the test case, refer to the projects fixture as well as the clients fixture. Hope that helps ! -- François Beausoleil http://blog.teksol.info/ _______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails