0

次のように定義された懸念があります。

module Shared::Injectable 
  extend ActiveSupport::Concern

  module ClassMethods
    def injectable_attributes(attributes)
      attributes.each do |atr|
        define_method "injected_#{atr}" do
           ...
        end
      end
    end
  end

そして、このような懸念を使用するさまざまなモデル:

Class MyThing < ActiveRecord::Base
  include Shared::Injectable
  ...
  injectable_attributes [:attr1, :attr2, :attr3, ...]
  ...
end

これは意図したとおりに機能し、クラスのインスタンスで呼び出すことができる一連の新しいメソッドを生成します。

my_thing_instance.injected_attr1
my_thing_instance.injected_attr2
my_thing_instance.injected_attr3

私の問題は、懸念をテストしようとしているときに発生します。生成された関数はすべて同じことを行うため、懸念を使用するすべてのモデルのテストを手動で作成することは避けたいと思います。代わりに、rspec を使用shared_example_forしてテストを 1 回記述し、rspec を使用して必要なモデルでテストを実行できると考えましたit_should_behave_like。これはうまく機能しますが、injectable_attributes関数に渡したパラメーターへのアクセスに問題があります。

現在、共有仕様内で次のようにしています。

shared_examples_for "injectable" do |item|
  ...
  describe "some tests" do
    attrs = item.methods.select{|m| m.to_s.include?("injected") and m.to_s.include?("published")}
    attrs.each do |a|
      it "should do something with #{a}" do
        ...
      end
    end
  end
end

これは機能しますが、これを行うには明らかに恐ろしい方法です。クラスインスタンスで既に定義されているメソッドを見るのではなく、クラスのインスタンスまたはクラス自体を介して、injectable_attributes 関数に渡された値のみにアクセスする簡単な方法はありますか?

4

2 に答える 2

1

「生成された関数はすべて同じことを行うため、懸念を使用するすべてのモデルのテストを手動で作成することを避けたい」と言うので、モジュールを分離してテストする仕様はどうですか?

module Shared
  module Injectable
    extend ActiveSupport::Concern

    module ClassMethods
      def injectable_attributes(attributes)
        attributes.each do |atr|
          define_method "injected_#{atr}" do
            # method content
          end
        end
      end
    end
  end
end

RSpec.describe Shared::Injectable do
  let(:injectable) do
    Class.new do
      include Shared::Injectable

      injectable_attributes [:foo, :bar]
    end.new
  end

  it 'creates an injected_* method for each injectable attribute' do
    expect(injectable).to respond_to(:injected_foo)
    expect(injectable).to respond_to(:injected_bar)
  end
end

次に、オプションとして、オブジェクトが実際に注入可能な属性を持っているかどうかをテストするための一般的な仕様を書きたい場合は、モジュールの仕様で得たものを繰り返さずに、次のようなものをMyThing仕様ファイルに追加できます。

RSpec.describe MyThing do
  let(:my_thing) { MyThing.new }

  it 'has injectable attributes' do
    expect(my_thing).to be_kind_of(Shared::Injectable)
  end
end
于 2016-03-11T21:57:34.437 に答える
0

次のようなことを試してみてはどうでしょうか。

class MyModel < ActiveRecord::Base
  MODEL_ATTRIBUTES = [:attr1, :attr2, :attr3, ...]
end

it_behaves_like "injectable" do 
  let(:model_attributes) { MyModel::MODEL_ATTRIBUTES }
end

shared_examples "injectable" do
  it "should validate all model attributes" do 
    model_attributes.each do |attr|
      expect(subject.send("injected_#{attr}".to_sym)).to eq (SOMETHING IT SHOULD EQUAL)
    end
  end
end

属性ごとに個別のテスト ケースを作成するわけではありませんが、属性ごとにアサーションが必要です。これにより、少なくとも何か作業ができるようになる可能性があります。

于 2016-03-11T21:36:28.303 に答える