1

これはすべて Rails 2.3.5 では問題なく動作しましたが、請負業者が 2.3.14 に直接アップグレードすると、突然すべての統合テストで次のように言われました。

NoMethodError: You have a nil object when you didn't expect it!
You might have expected an instance of ActiveRecord::Base.
The error occurred while evaluating nil.[]

一部の JavaScript が使用する Cookie の束を設定する ApplicationController に before_filter があり、Cookie の値を設定する行の 1 つを除いてすべてコメントアウトすると、正常に動作し、どの行でも問題ないことがわかりました。私は去ります。

before_filter :set_cookies

def set_cookies
  cookies['logged_in'] = (logged_in ? 'y' : 'n')
  cookies['gets_premium'] = (gets_premium ? 'y' : 'n')
  cookies['is_admin'] = (is_admin ? 'y' : 'n')
end

これらの行の 1 つだけがアクティブな場合、統合テストではすべて問題ありませんが、それ以外の場合は上記のエラーが発生します。たとえば、次のテスト/レスポンスを考えてみましょう:

test "foo" do
  get '/'
end


$ ruby -I"lib:test" test/integration/foo_test.rb -n test_foo -v
Loaded suite test/integration/foo_test
Started
test_foo(FooTest): E

Finished in 5.112648 seconds.

  1) Error:
test_foo(FooTest):
NoMethodError: You have a nil object when you didn't expect it!
You might have expected an instance of ActiveRecord::Base.
The error occurred while evaluating nil.[]
    test/integration/foo_test.rb:269:in `test_foo'

1 tests, 0 assertions, 0 failures, 1 errors

しかし、これらの Cookie 設定行のいずれか 2 つがコメント アウトされている場合は、次のようになります。

$ ruby -I"lib:test" test/integration/foo_test.rb -n test_foo -v
Loaded suite test/integration/foo_test
Started
test_foo(FooTest): .

Finished in 1.780388 seconds.

1 tests, 0 assertions, 0 failures, 0 errors

開発モードと本番モードで実行されている Web サイトは正常に動作します。これは、テストに合格するだけの問題です。また、デバッグ出力を使用して、Cookie が設定されたメソッドでエラーがスローされないこと、すべてが正常に実行されること、エラーが発生するのは後でどこかであることを確認しました (ただし、バックトレースでは場所がわかりません)。

4

3 に答える 3

2

L0neの答えは私にとってはうまくいきますが、これも含める必要があります-environment.rbファイルの最後で必要な場合は、lib/rack_rails_cookie_header_hack.rbの最後に配置できます-つまり、Rails::Initializerの後に実行しました:

ActionController::Dispatcher.middleware.insert_before(ActionController::Base.session_store, RackRailsCookieHeaderHack)
于 2012-07-03T13:14:18.620 に答える
2

これは、rack rack がセッション Cookie とともに Cookie をクライアントに書き込む方法のバグであることが判明しました。Rack は二重の改行を含み、セミコロンを省略していました。

Firefox のようなブラウザーは、軽度に不正な形式の Cookie データを処理できますが、統合テスト クライアントは処理できませんでした。

これを修正するには、クライアントに送信する前に Cookie ヘッダーを書き直す必要がありました。

environment.rb で:

require 'rack_rails_cookie_header_hack'

lib/rack_rails_cookie_header_hack.rb では:

class RackRailsCookieHeaderHack

  def initialize(app)
    @app = app
  end

  def call(env)
    status, headers, body = @app.call(env)
    if headers['Set-Cookie']
      cookies = headers['Set-Cookie']
      cookies = cookies.split("\n") if is_str = cookies.is_a?(String)
      if cookies.respond_to?(:collect!)
        cookies.collect! { |h| h.strip }
        cookies.delete_if { |h| h.empty? }
        cookies.collect! { |h| h.include?(';') ? h : h + ';' }
      end
      headers['Set-Cookie'] = is_str ? cookies.join("\n").strip : cookies
    end
    [status, headers, body]
  end
end

申し訳ありませんが、ソースが明確にされていません。私は実際にこれを少し前に修正し、この質問に出くわし、パッチを投稿すると考えました。

于 2012-06-21T23:02:22.423 に答える
0

古い忘れられた問題...

私は Lone の修正をテストしていませんが、彼は問題を正しく認識しています。例外をキャッチして を使用して印刷するexception.backtraceと、問題が原因であることがわかります。 gems/actionpack/lib/action_controller/integration.rb:329

問題のあるコードは次のとおりです。

cookies.each do |cookie|
  name, value = cookie.match(/^([^=]*)=([^;]*);/)[1,2]
  @cookies[name] = value
end

あなたが私のようで、いくつかの非常に迅速な統合テストにのみ興味があり、将来の保守性についてあまり気にしない場合 (これは Rails 2 であるため)、そのメソッドに条件付きフィルターを追加するだけです。

cookies.each do |cookie|
  unless cookie.blank?
    name, value = cookie.match(/^([^=]*)=([^;]*);/)[1,2]
    @cookies[name] = value
  end
end

そして問題は解決しました

于 2013-09-05T17:41:24.490 に答える