2011-09-28 8 views
5

私に何か不足しているような気がします。私は、主な機能を追加するためのアクティブなレコードとの対話を可能にするルビーの宝石を書いています。dbを使用しないアクティブレコードモデルを偽装する

テストケースを書く際に、この機能をテストするためにダミーのアクティブレコードモデルを指定できる必要があります。データベースに接続する必要のないアクティブなレコードモデルのインスタンスを得ることができれば、すばらしいことです。それは関係を持つことができますが、データベースにテーブルを設定する必要はありません。私はかなり新しいテストをしています。レールテストの外では、私はかなり新しくなりましたが、それはかなり容易にできるはずですが、何も見つけられません。

誰かが私に行方不明を教えてもらえますか?私は工場、製作者、備品などを見てきましたが、そのすべてがDBに当たっているようです。どのように人々はテストのためだけにARオブジェクトが必要な宝石をテストしますか?

答えて

8

でそれについて話す:

NullDBはActiveRecordのデータベースアダプタに適用されるヌルオブジェクトパターンです。これは、データベースの対話をno-opsに変換するデータベースバックエンドです。 NullDBを使用すると、実際のデータベースに触れることなく、モデルのビジネスロジック(after_saveフックを含む)をテストできます。

+0

これはまさに私が探していたものです。ありがとう! –

+0

このライブラリの欠点は、Rspecにどのように結合されているかです。あなたがRspec –

+0

+1を使っていない場合、私の側から覚えておくべきこと... –

2

他にも同じ問題があります。私の普通の取り組みは、単体テストのための模擬ライブラリを使用し、模擬するにはあまりにも複雑な設定(何らかの方法を避けるべき)のためにそれらを補完するためのフィクスチャを使って機能的なものを書くことです。

または、同じインターフェイスを提供するがDBを必要としないARの置換ライブラリを使用してください。私はしばらくの間レールを使用していませんでしたが、以前はレールがありました。これらのライブラリは通常(Webサービス、LDAPなどの)他の要件を持っているため、またはモックと同じ単一のレコード設定作業が必要なため、DBを使用する場合と全く同じ問題はありません。

これを咬合して治具を使うだけですが、メモリとsqlite DBをテスト用に使い、適切な移行を行うことでコストが非常に小さくなります。

+0

あなたは良い点を作っています。小さなsqlite dbは良い選択肢になります。 –

2

ええ、私はこれをRails 2.3でやり直したいと思っていました。 ActiveModelを使用すると、独自のロールを作成したい場合は、明示的なインタフェースを提供する方が簡単になると思います。

また、自分で使ったことはありませんが、Josh SusserにはAR-ishの動作をどのクラスにも組み込むことができる宝石があります。これはフォームに普通のルビーオブジェクトを使うようになっているようですが、単体テストにも役に立ちます。 informalを参照してください。

彼はあなたがNullDBを必要とするようですね、最近Ruby Rogues episode

+0

非公式の外見は本当にクールです。私は実際にこれを他の何かのために使うかもしれません、それを指摘してくれてありがとう。 –

1

もう1つの方法として、sqlite3アダプタを使用してデータベースをメモリ上で実行し、DatabaseCleanerを使用してテスト後のレコードを削除します。

このアプローチにはいくつかの利点があります、あなたがテストにSQLを見ることができます

  • クエリ最適化プロセス
  • を簡素化することは、「現実の生活」の例で

に近いですもう少し時間がかかりますが、それを再構成しても構わないと思います)

ここでは簡単な説明が必要ですRそれは:私は事を保つために、次のアプローチを使用していますが、あなたは歓迎されている

# in Gemfile 
gem "activerecord" #since you are dealing with activerecord 
gem "database_cleaner", :group => :test 
gem "sqlite3", :group => :test 

異なり、それを持っている:

# in RAILS_ROOT/test/support/active_record.rb 
require 'logger' 

ActiveRecord::Base.establish_connection(
    :adapter => "sqlite3", :database => ':memory:' 
) 

#this line will print the SQL queries right into console 
ActiveRecord::Base.logger = Logger.new(STDOUT) 

# in RAILS_ROOT/test/support/database_cleaner.rb 
require 'database_cleaner' 
DatabaseCleaner.strategy = :truncation 
# or DatabaseCleaner.strategy = :trunsaction (it is up to you) 

module OrmSetup 
    def before_setup 
    DatabaseCleaner.start 
    end 

    def after_teardown 
    DatabaseCleaner.clean 
    end 
end 

# in RAILS_ROOT/test/test_helper.rb 
... 
require File.expand_path("support/active_record", File.dirname(__FILE__)) 
require File.expand_path("support/database_cleaner", File.dirname(__FILE__)) 

class Test::Unit::TestCase 
    include OrmSetup 
end 

そして今、あなたのテストであなたが持つことができる何かを

のように
require 'test_helper' 

class User < ActiveRecord::Base 
end 

class MyFancyTest < Test::Unit::TestCase 
    def setup 
    before_setup 
    end 

    def teardown 
    after_teardown 
    end 
end 
関連する問題