gpt4 book ai didi

ruby - 使用 RSpec double 测试 obj.extend(Foo)

转载 作者:太空宇宙 更新时间:2023-11-03 16:45:23 24 4
gpt4 key购买 nike

RSpec doubles 不能通过扩展它的实例来改变。

最小示例

请注意这里描述的例子只是一个最小的例子来证明问题。原始类更复杂,指定的行为 (obj.extend(Something)) 是必需的,并且无法更改。

规范

让我们先看看规范。在下面的示例中,您可以看到我希望它看起来像的规范:

require 'spec_helper'

RSpec.describe Modifier do
subject(:modifier) { described_class.new(active) }

describe "#apply_to(obj)" do
subject(:obj) { instance_double(Foo, foo: "foo") }

before { modifier.apply_to(obj) }

context "when active" do
let(:active) { true }
its(:foo) { is_expected.to eq("extended-foo") } # NOTE: This one will fail
end

context "when not active" do
let(:active) { false }
its(:foo) { is_expected.to eq("foo") }
end
end
end

不幸的是,这不起作用:(

Failures:

1) Modifier#apply_to(obj) when active foo should eq "extended-foo"
Failure/Error: its(:foo) { is_expected.to eq("extended-foo") }

expected: "extended-foo"
got: "foo"

class Foo
attr_reader :foo

def initialize(foo)
@foo = foo
end
end

修饰符

此类将通过扩展其实例方法来修改给定的对象。

class Modifier
def initialize(active)
@active = active
end

# NOTE: This is the interesting method
def apply_to(obj)
return unless active?

obj.extend(Extended) # NOTE: And this is the interesting LOC
end

def active?
@active
end

private

attr_reader :active

module Extended
def foo
"extended-#{super}"
end
end
end

更小的例子

整个问题可以分解为以下代码片段:

module Bar
def foo
"bar"
end
end

double = RSpec::Mocks::Double.new("Foo", foo: "foo")
obj = Object.new

double.extend(Bar)
obj.extend(Bar)

double.foo
# => "foo"

obj.foo
# => "bar"

结论

RSpec doubles 不能通过扩展它的实例来改变,这是预期的行为吗?

如果是这样,您如何为此处描述的示例创建可读的规范?

链接

最佳答案

如果规范知道它需要一个扩展对象,为什么不期望extend 调用它自己呢?

expect(obj).to receive(:extend).and_return { class.new.extend(...) }

关于ruby - 使用 RSpec double 测试 obj.extend(Foo),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33997298/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com