0

これは、あなたが気が狂っていると思わせるものの1つです...

クラス Section と、それを継承する DraftSection があります。

(簡潔にするためにトリミングされています)

class Section
  include Mongoid::Document

  belongs_to :site

  field :name, type: String
end

class DraftSection < Section
  field :name, type: String, default: "New Section"
end

すべての単純なもの...コンソールが証明します(ここでも、簡潔にするためにトリミングされています)

004 > site = Site.first
 => #<Site _id: initech, name: "INITECH"> 
005 > site.sections.build
 => #<Section _id: 1, site_id: "initech", name: nil> 
006 > site.draft_sections.build
 => #<DraftSection _id: 2, site_id: "initech", name: "New Section">

ご覧のとおり、ドラフト セクション名は、サブクラスでオーバーライドされるため、デフォルトで正しく「New Section」になります。

この仕様を実行すると、次のようになります。

describe "#new" do
  it "should return a draft section" do
    get 'new', site_id: site.id, format: :json
    assigns(:section).should == "Something..."
  end
end

このコントローラーメソッドをテストするもの:

def new
  @section = @site.draft_sections.build
  respond_with @section
end

これは(予想どおり)失敗しますが、次の場合:

Failure/Error: assigns(:section).should == "Something..."
   expected: "Something..."
        got: #<DraftSection _id: 1, site_id: "site-name-4", name: nil> (using ==)

何を与える?

アップデート:

さまざまな環境設定の問題である可能性があると考えたので、mongoid.yml 構成ファイルを調べたところ、オプションで次のことがわかりました。

# Preload all models in development, needed when models use
# inheritance. (default: false)
preload_models: true

テスト環境の設定にも追加しましたが、まだ喜びはありません:(

更新 2 - プロットが厚くなります...

テスト環境でコンソールをロードして、以前と同じことを試してみようと思いました:

001 > site = Site.first
 => #<Site _id: initech, name: "INITECH"> 
002 > site.draft_sections.build
 => #<DraftSection _id: 1, site_id: "initech", name: "New Section">

なんてこと?

4

1 に答える 1

0

わかりました、誰も聞いていませんが、今後の参考のためにここに解決策を投稿します...

何らかの理由で、少し前に、このコードを Spork.each_run ブロックに残してしまったことを意味するデバッグ セッションがありました。

  # Reload all model files when run each spec
  # otherwise there might be out-of-date testing
  # require 'rspec/rails'
  Dir["#{Rails.root}/app/controllers//*.rb"].each do |controller|
    load controller
  end
  Dir["#{Rails.root}/app/models//*.rb"].each do |model|
    load model
  end
  Dir["#{Rails.root}/lib//*.rb"].each do |klass|
    load klass
  end

これにより、スペックを実行するたびにモデルがリロードされていました。当然のことながら、これにより、spec の実行中にクラスがメモリにセットアップされる方法が台無しになりました。

デバッグが非常に困難だった理由を明確に説明しています...

したがって、Rspec のみで同様の継承の問題を抱えている将来の Google 社員のために、テスト スタックのどこにもモデルをリロードするものがないことを確認してください。

于 2012-11-20T18:40:23.317 に答える