Forum: Ruby on Rails How to write unit tests with respect to model callbacks?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
3a18f0e7810b93223a39bf00c9d403b5?d=identicon&s=25 Frodo Larik (Guest)
on 2005-12-22 11:44
(Received via mailing list)
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
3dd4b52a0946bd698b1d1635a46ea3a3?d=identicon&s=25 Francois Beausoleil (Guest)
on 2005-12-22 13:35
(Received via mailing list)
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 !
This topic is locked and can not be replied to.