RSpec - bogus (or stub) overmixing method

I have a situation like this:

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

      

Now the problem is with testing - I would like the super method to receive a call from the overriden method and stub it so that I can test other parts of the method. How can I accomplish this using RSpec mocks?

+3


source to share


1 answer


Ensuring what super

happens to be called sounds like testing the implementation, not the behavior, and mocking the subject is not such a great idea. I would suggest to just explicitly specify different code paths

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

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

      

If you had many classes that included this module, you could use generic examples to reduce duplication in tests.

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

      

Refresh . If you really cannot predict the behavior of the mixin, you can disable the method being called by super

including another module that defines it.



If you have a class C

that includes modules M

and N

that define a method f

, then in C#f

, super

will refer to which module was last included.

class C
  include M
  include N

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

      

If you include it in your test subject's singleton class, it will not affect other tests:

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

      

Disclaimer: This doesn't actually check if the mixin is working, it just makes a call super

. I would still advise to actually test the behavior.

+7


source







All Articles