views:

16

answers:

1

I wrote a little monkeypatch to the Rails MySQLAdapter and want to package it up to use it in my other projects. I am trying to write some tests for it but I am still new to testing and I am not sure how to test this. Can someone help get me started?

Here is the code I want to test:

unless RAILS_ENV == 'production'
      module ActiveRecord
        module ConnectionAdapters
          class MysqlAdapter < AbstractAdapter
            def select_with_explain(sql, name = nil)
              explanation = execute_with_disable_logging('EXPLAIN ' + sql)
              e = explanation.all_hashes.first
              exp = e.collect{|k,v| " | #{k}: #{v} "}.join
              log(exp, 'Explain')
              select_without_explain(sql, name)
            end

            def execute_with_disable_logging(sql, name = nil) #:nodoc:
              #Run a query without logging
              @connection.query(sql)
            rescue ActiveRecord::StatementInvalid => exception
              if exception.message.split(":").first =~ /Packets out of order/
                raise ActiveRecord::StatementInvalid, "'Packets out of order' error was received from the database. Please update your mysql bindings (gem install mysql) and read http://dev.mysql.com/doc/mysql/en/password-hashing.html for more information.  If you're on Windows, use the Instant Rails installer to get the updated mysql bindings."
              else
                raise
              end
            end
            alias_method_chain :select, :explain
          end
        end
      end
    end

Thanks.

A: 

General testing

You could start reading about testing.

After you are understanding the basics of testing, you should think what you have changed. Then make some tests which test for

  • the original situation, resulting in errors since you updated it. So reverse the test after it indeed is working for the original situation.
  • the new situation to see whether you have implemented your idea correctly

The hardest part is to be sure that you covered all situations. Finally, if both parts pass then you could say that your code it working as expected.

Testing gems

In order to test gems you can run

rake test:plugins

to test all plugins of your rails application (see more in chapter 6 of the testing guide), this only works when the gem is in the vendor directory of an application.

Another possibility is to modify the Rakefile of the gem by including a testing task. For example this

desc 'Test my custom made gem.'
Rake::TestTask.new(:test) do |t|
  t.libs << 'lib'
  t.libs << 'test'
  t.pattern = 'test/**/*_test.rb'
  t.verbose = true
end

would run all available tests in the test directory ending with _test.rb. To execute this test you can type rake test (from the gem directory!).

In order to run the tests for the gem by default (when typing just rake) you can add/modify this line:

task :default => :test

I used the second method in my ruby-bbcode gem, so you could take a look at it to see the complete example.

Veger
I definitely have been reading about testing. I am getting used to the basics of it now. I am just a little unsure about how to deal with this because its specific to the mysql adapter and I will need to pull in ActiveRecord and then apply my patch in the test then call reponds_to? or something to see if it reacts to the methods I added? Am I in the ballpark here?
Mike Williamson
I do not understand your code, don't know what you want to achieve. But it changes the behavior of the mysql adapter, so just check whether this change in behavior matches your expected behavior. In your situation you probably should grab some ActiveRecords indeed to see whether the mysql adapter is working properly. You could skip testing the result for the original situation if it is too hard to apply the patch dynamically (depending on your test).
Veger
The code simply runs a MySQL EXPLAIN statement before every select is run. Its just to help remind me to add indexes. I am finding the testing confusing because I want to package this up separate from a rails app. I want it to be a gem so I can use it with my other projects. So how can I test my changes to a mysql connection when there is no Rails app around? Where would it get its connection credentials from? is it possible to test this sort of thing separately?
Mike Williamson
Oh... I did not understood you wanted to test a gem, I added some explanation for that to my answer.
Veger