3

ここ数週間、問題を解決しようとしています。Rails アプリの rspec テストを実行していますが、理解できないエラーが 1 つある以外は問題なく動作しています。

  • InnoDB エンジンで MySQL を使用しています。
  • config.use_transactional_fixtures = truespec_helper.rbに設定しました
  • コマンドを使用して、テスト フィクスチャを手動でロードしますrake spec:db:fixtures:load
  • rspec テストは BackgrounDRb ワーカー向けに作成されており、(state_machine gem を介して) レコードの状態を更新できることをテストしています。

これが私の問題です:

というモデルがありListingsます。rspec テストは、update_sold_itemsというファイル内のメソッドを呼び出しますlisting_worker.rb。このメソッドはlisting.sell特定のレコードを呼び出し、リスト レコードの「状態」列を「販売済み」に設定します。これまでのところ、これはすべて正常に機能していますが、update_sold_itemsメソッドが終了すると、rspec テストはここで失敗します。

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

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

状態の変化が持続しない理由を突き止めようとしていますが、ほとんど失われています。update_sold_itemsテスト中にメソッドに配置したデバッグ コードの結果を次に示します。

pp listing.state  # => "current"

listing.sell!
listing.save!

pp listing.state  # => "sold"

listing.reload

pp listing.state  # => "current"

reloadなぜそれが完全にうまく保存されるのか理解できませんが、呼び出すたびに元のレコードに戻りますListing.find.

これを読んでくれてありがとう。十分な情報を提供していない場合は、質問してください。

助けてくれてありがとう、ネイサン・B

PS他のクラスの新しいレコードを作成し、それらのレコードをテストすることに問題はありません。データベースに既に存在するレコードを更新している場合にのみ問題になるようです。

4

2 に答える 2

1

ネイサンのように、トランザクションの問題を疑っています。最初の保存呼び出しの直前に Listing.connection.execute("COMMIT") を配置して、トランザクションを中断し、何が変化するかを確認してください。これにより、トランザクションが中断されるため、追加のロールバック呼び出しは無効になります。

さらに、「COMMIT」コマンドを実行すると、デバッガーでテストを一時停止し、別のクライアントからデータベースを調べて、何が起こっているかを確認できます。

もう 1 つの仮説として、トランザクションの実験で結果が得られない場合は、モデルが実際にはデータベースに保存されていない可能性があります。クエリ ログを確認します。(具体的には、更新クエリを見つけます)。

この種の問題は本当に臭いです!幸運を!

于 2010-03-30T17:42:34.163 に答える
0

テストの実行中にDBにあるものを調査したい場合は、これが役立つかもしれません...

@user.save を保存する rspec テストがあり、魅力的に機能しますが、実際に DB に保存されているかどうかを確認したかったのです。

テスト環境用に Rails コンソールを開きました

rails c test

走った

User.all

そして予想通り何も得られなかった

以下を含む仕様を実行しました。

user_attr_hash    = FactoryGirl.attributes_for(:user)
@user = User.new user_attr_hash
@user.save
binding.pry

保存後にテストを停止すると永続化されると思っていましたが、そうではありません。接続の COMMIT は後で起動されるようです (いつになるかはわかりません:\ ) したがって、@Tim Harper が示唆するように、pry コンソールでそのコミットを自分で起動する必要があります。

pry(#<RSpec::Core::ExampleGroup::Nested_1>)> User.connection.execute("COMMIT")

ここで、Rails コンソールで User.all を実行すると、それが表示されるはずです;)

于 2014-05-30T11:23:12.170 に答える