Reputation: 8448
I have situaltion 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 to ensure that super method got called from overriden method and stub it so that I can test other parts of method. How can I accomplish that using RSpec mocks?
Upvotes: 4
Views: 2986
Reputation: 6644
Ensuring that super
gets called sounds a lot like testing the implementation, not the behaviour, and mocking the subject-under-test isn't such a great idea anyway. I would suggest just explicitly specifying the 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 a lot of classes that included that module, you could use shared examples to reduce the duplication in your 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
Update: If you really can't predict the behaviour of the mixin, you could switch out what method gets called by super
by including another module that defines it.
If you have a class C
that includes modules M
and N
that both define a method f
, then in C#f
, super
will refer to whichever module was included last.
class C
include M
include N
def f
super # calls N.f because it was included last
end
end
If you include it in the singleton class of your subject-under-test, then it won't affect any 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 test that the mixin works, just that super
gets called. I still would advise actually testing the behaviour.
Upvotes: 8