3

私はこのような状況にあります:

module Something
  def my_method
    return :some_symbol
  end
end

class MyClass
  include Something

  def my_method
    if xxx?
      :other_symbol
    else
      super
    end
  end
end

ここで問題はテストにあります-オーバーライドされたメソッドからスーパーメソッドが呼び出されたことを確認し、メソッドの他の部分をテストできるようにスタブ化します。RSpecモックを使用してそれを達成するにはどうすればよいですか?

4

1 に答える 1

7

それが確実superに呼び出されるようにすることは、振る舞いではなく実装をテストすることによく似ています。異なるコードパスを明示的に指定することをお勧めします

describe "#my_method" do
  it "returns :other_symbol when xxx" do
    ...
  end

  it "returns :some_symbol when not xxx" do
    ...
  end
end

そのモジュールを含むクラスが多数ある場合は、共有例を使用してテストの重複を減らすことができます。

shared_examples_for "Something#my_method" do
  it "returns :some_symbol" do
    expect(subject.my_method).to eq :some_symbol
  end
end

describe MyClass do
  describe "#my_method" do
    context "when xxx" do
      subject { ... }

      it "returns :other_symbol" do
        expect(subject.my_method).to eq :other_symbol
      end
    end

    context "when not xxx" do
      subject { ... }

      it_behaves_like "Something#my_method"
    end
  end
end

更新:ミックスインの動作を本当に予測できない場合はsuper、それを定義する別のモジュールを含めることで、どのメソッドが呼び出されるかを切り替えることができます。

Cモジュールを含むMクラスがあり、Nその両方がメソッドを定義している場合f、 in はC#fsuper最後にインクルードされたモジュールを参照します。

class C
  include M
  include N

  def f
    super # calls N.f because it was included last
  end
end

サブジェクト アンダー テストのシングルトン クラスに含めると、他のテストには影響しません。

describe MyClass do
  describe "#my_method" do
    it "calls super when not xxx" do
      fake_library = Module.new do
        def my_method
          :returned_from_super
        end
      end

      subject.singleton_class.send :include, fake_library

      expect(subject.my_method).to be :returned_from_super
    end
  end
end

免責事項: これは mixin が機能することを実際にテストするものではなく、super呼び出されるだけです。実際に動作をテストすることをお勧めします。

于 2013-01-27T12:23:16.170 に答える