2

Rails アプリに次のオブジェクト構造があります。

# app/models/model_a/model_b/model_c.rb
class ModelA < ActiveRecord::Base
  class ModelB < ActiveRecord::Base
    class ModelC < ActiveRecord::Base
    end
  end
end

# app/presenters/model_a/model_b/presenter_for_model_c.rb
class ModelA::ModelB::PresenterForModelC
end

現在、RSpec を使用して PresenterForModelC を分離してテストしたい場合、テストをrequire 'spec_helper'高速に実行する必要はありません ( Corey HainesまたはGary Bernhardtのように)。代わりに、プレゼンターを直接ロードしようとしています。 :

# spec/presenters/model_a/model_b/presenter_for_model_c_spec.rb
require_relative '../../../app/presenters/model_a/model_b/presenter_for_model_c'
describe ModelA::ModelB::PresenterForModelC do
end

ただし、これは次の場合に失敗します。

uninitialized constant ModelA (NameError)

次のようなスタブ化された構造を作成することはできません。

# spec/presenters/model_a/model_b/presenter_for_model_c_spec.rb
class ModelA
  class ModelB
  end
end
require_relative '../../../app/presenters/model_a/model_b/presenter_for_model_c'

モデルがロードされたときにクラスが同じ親から継承されないため、完全なスイートを実行すると問題が発生するためです。同様に、モジュールを使用できません (同じ理由で)。私も避けたい:

# spec/presenters/model_a/model_b/presenter_for_model_c_spec.rb
class ModelA < ActiveRecord::Base
  class ModelB < ActiveRecord::Base
  end
end
require_relative '../../../app/presenters/model_a/model_b/presenter_for_model_c'

これは、高速仕様の目的を無効にする ActiveRecord を要求することを余儀なくされるためです。

私が思いついた他の唯一の解決策は、プレゼンターを独自の名前空間に移動することです。Presenters::ModelA::ModelB::PresenterForModelCここでPresenters::ModelA、 とPresenters::ModelBはクラスではなくモジュールになります。このアプローチの欠点は、app/presenters/presentersオートローディングを機能させるためにディレクトリを作成する必要があることです。これは少し面倒だと思います。

他の選択肢はありますか?

4

0 に答える 0