如何用RSpec的mock或stub实现mixin方法的覆盖?

2026-04-11 17:181阅读0评论SEO基础
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计492个文字,预计阅读时间需要2分钟。

如何用RSpec的mock或stub实现mixin方法的覆盖?

我遇到了这样的问题:我有一个模块定义,如下所示:

rubymodule Something def my_method :some_symbol endend

class MyClass include Something def my_method if xxx? :other_symbol else super end endend

现在的问题是测试——我想确保从 override 方法调用 super。

我有这样的情况:

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

现在的问题是测试 – 我想确保从override方法调用super方法并将其存根以便我可以测试方法的其他部分.如何使用RSpec模拟实现这一目标?

确保超级被调用听起来很像测试实现,而不是测试行为,并且模拟测试对象无论如何都不是一个好主意.我建议只是明确指定不同的代码路径

如何用RSpec的mock或stub实现mixin方法的覆盖?

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

更新:如果你真的无法预测mixin的行为,你可以通过包含另一个定义它的模块来切换super调用的方法.

如果你有一个包含模块M和N的C类,它们都定义了方法f,那么在C#f中,super将引用最后包含的模块.

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调用了.我仍然会建议实际测试行为.

本文共计492个文字,预计阅读时间需要2分钟。

如何用RSpec的mock或stub实现mixin方法的覆盖?

我遇到了这样的问题:我有一个模块定义,如下所示:

rubymodule Something def my_method :some_symbol endend

class MyClass include Something def my_method if xxx? :other_symbol else super end endend

现在的问题是测试——我想确保从 override 方法调用 super。

我有这样的情况:

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

现在的问题是测试 – 我想确保从override方法调用super方法并将其存根以便我可以测试方法的其他部分.如何使用RSpec模拟实现这一目标?

确保超级被调用听起来很像测试实现,而不是测试行为,并且模拟测试对象无论如何都不是一个好主意.我建议只是明确指定不同的代码路径

如何用RSpec的mock或stub实现mixin方法的覆盖?

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

更新:如果你真的无法预测mixin的行为,你可以通过包含另一个定义它的模块来切换super调用的方法.

如果你有一个包含模块M和N的C类,它们都定义了方法f,那么在C#f中,super将引用最后包含的模块.

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调用了.我仍然会建议实际测试行为.