views:

225

answers:

1

I've been trying to solve a problem for a few weeks now. I am running rspec tests for my Rails app, and they are working fine except for one error that I can't seem get my head around.

  • I am using MySQL with the InnoDB engine.
  • I have set config.use_transactional_fixtures = true in spec_helper.rb
  • I load my test fixtures manually with the command rake spec:db:fixtures:load.
  • The rspec test is being written for a BackgrounDRb worker, and it is testing that a record can have its state updated (through the state_machine gem).

Here is my problem:

I have a model called Listings. The rspec test calls the update_sold_items method within a file called listing_worker.rb. This method calls listing.sell for a particular record, which sets the listing record's 'state' column to 'sold'. So far, this is all working fine, but when the update_sold_items method finishes, my rspec test fails here:

listing = Listing.find_by_listing_id(listing_id)
listing.state.should == "sold"

expected: "sold",
     got: "current" (using ==)

I've been trying to track down why the state change is not persisting, but am pretty much lost. Here is the result of some debugging code that I placed in the update_sold_items method during the test:

pp listing.state  # => "current"

listing.sell!
listing.save!

pp listing.state  # => "sold"

listing.reload

pp listing.state  # => "current"

I cannot understand why it saves perfectly fine, but then reverts back to the original record whenever I call reload, or Listing.find etc.

Thanks for reading this, and please ask any questions if I haven't given enough information.

Thanks for your help, Nathan B

P.S. I don't have a problem creating new records for other classes, and testing those records. It only seems to be a problem when I am updating records that already exist in the database.

A: 

I suspect, like nathan, transaction issues. Try putting a Listing.connection.execute("COMMIT") right before your first save call to break the transaction and see what changes. That will break you out of the transaction so any additional rollback calls will be non-effectual.

Additionally, by running a "COMMIT" command, you could pause the test with a debugger and inspect the database from another client to see what's going on.

The other hypothesis, if the transaction experimentation doesn't yield any results, is that perhaps your model really isn't saving to the database. Check your query logs. (Specifically find the update query).

These kind of issues really stink! Good luck!

Tim Harper
Thanks for pointing me in the right direction!! I finally worked out that I was overriding the models 'update' method, and felt like an idiot. Thanks!!
nathan.f77