2012-01-22 3 views
0

私はRailsでテストするのが初めてで、このユニットテストが失敗する理由を理解できません。基本的に、私はこの単体テストが1つのレコードをテストデータベースに入力することを期待しています。奇妙な理由から、テストは失敗しますが、テストデータベースには2つのレコードが追加されます。これは非常に奇妙な動作です。 'rails c test'を使い、 'Thing.all'を入力すると、これはテストを実行する前とテストを実行した後の結果です。Rails(newbie)で単体テストに問題があります。奇妙な予期しない動作

テスト(すくいデシベルを実行した後:テスト:レールコンソールで準備し、その後Thing.all):以前にテストした後

Thing Load (0.5ms) SELECT "things".* FROM "things" 
=> [] 

Thing Load (0.6ms) SELECT "things".* FROM "things" 
=> [#<Thing id: 980190962, name: "MyNameAgain", created_at: "2012-01-22 17:34:25", updated_at: 
"2012-01-22 17:34:25", description: "MyDescription">, #<Thing id: 298486374, name: "Hello", 
created_at: "2012-01-22 17:34:25", updated_at: "2012-01-22 17:34:25", description: 
"HelloDescription">] 

だからここにはありますユニットテスト:

require 'test_helper' 
require 'awesome_print' 

class ThingTest < ActiveSupport::TestCase 

    setup do 
    @example = Thing.new(things(:one).attributes) 
    # Must set id manually 
    @example.id = things(:one).id 
    end 

    test 'thing can be created' do 
    ap @example 
    ap @example.valid? 
    ap @example.errors 
    assert @example.save 
    end 

end 

出力素晴らしい印刷からは、以下である:

ここでは
#<Thing:0x007fda8c1d99f8> { 
      :id => 980190962, 
      :name => "MyNameAgain", 
    :created_at => Sun, 22 Jan 2012 17:17:08 UTC +00:00, 
    :updated_at => Sun, 22 Jan 2012 17:17:08 UTC +00:00, 
    :description => "MyDescription" 
} 
false 
#<ActiveModel::Errors:0x7fda8c064000 
    @base = #<Thing:0x007fda8c1d99f8> { 
       :id => 980190962, 
       :name => "MyNameAgain", 
     :created_at => Sun, 22 Jan 2012 17:17:08 UTC +00:00, 
     :updated_at => Sun, 22 Jan 2012 17:17:08 UTC +00:00, 
     :description => "MyDescription" 
    }, 
    attr_reader :messages = { 
     :name => [ 
      [0] "has already been taken" 
     ] 
    } 
> 
F 
Finished in 0.186603 seconds. 

    1) Failure: 
test_thing_can_be_created(ThingTest) [/Users/sb1752/Dropbox/Coding/GeneralAssembly/class_RubyForDevs/4-rails-mvc/4.3-rails-dev/test/unit/thing_test.rb:16]: 
Failed assertion, no message given. 

1 tests, 1 assertions, 1 failures, 0 errors, 0 skips 

治具である:ここでは

one: 
    name: MyNameAgain 
    description: MyDescription 

two: 
    name: Hello 
    description: HelloDescription 

はモデルです:

class Thing < ActiveRecord::Base 
    validates :name, :uniqueness => true, :presence => true 
end 

は、あなたがどんなより多くの情報が必要なら、私を知ってみましょう!ありがとう!

+0

検証で見つかったエラーを表示できますか? 'ap @ example.errors'です。 IDが設定されていない理由は、あなたが大量割り当てを使用しているからです - http://stackoverflow.com/questions/1262629/ruby-on-rails-id-not-saving – PinnyM

+0

ありがとう@PinnyM、私はエラーを表示し、上記の投稿に表示しました。 idを手動で設定して、現在実際に動作していることを確認しました。しかし、エラーはまだ奇妙です。もう一回見てもらえますか? – Shaan

+0

テストごとにテストデータベースが適切に切り捨てられているか、クリアされていますか? – nowk

答えて

2

あなたの質問を表現する方法に基づいて、私はあなたが器具の仕組みを完全に理解していないと推測しています。フィクスチャファイル(あなたの場合は 'things.yml')は、オブジェクトをデータベースにロードするために使用され、各テスト中にサンプルデータとして利用できます。 Thing.allを実行すると、フィクスチャファイルが作成したモデルが表示されます。

テスト中にあなたのモデルに:idを割り当てる理由はありません(おそらく)。一般的に、レールは自動増分データベースフィールドを作成し、アイテムが保存されるときにIDの設定を処理します。 (。そこには、IDを設定する必要が例外的な場合がありますが、これは標準ではありません)

が戻ってあなたの問題を取得するには、ここであなたが見ているの故障の原因となるエラーメッセージです:

:name => [ 
     [0] "has already been taken" 
    ] 

これは、あなたの検証要件validates :name, :uniqueness => trueが名前が一意である(複数のレコードで使用されていない)ことをチェックし、既存の名前を再利用できるようにしないためです:名前 - この場合、什器の1つは既にあなたの属性をコピーしているもの)。テストを変更する(作成する新しいモデルの名前を変更する)か、検証ルールを変更する必要があります。

テスト用の別のオプションは、テストモデルを作成するためのフィクスチャではなく、ファクトリ(FactoryGirlなど)を使用することです。

関連する問題