gpt4 book ai didi

ruby - RSpec 模拟失败 "undefined method ` -' for nil:NilClass"

转载 作者:数据小太阳 更新时间:2023-10-29 08:17:52 25 4
gpt4 key购买 nike

我想用 RSpec 测试一个简单的方法。我想确保 applyplayer.capacity 减一。为此,我模拟了一个播放器对象并正在测试它是否收到了正确的消息。

代码

class DecreaseCapacity < Item
def apply player
player.capacity -= 1
end
end

测试

describe DecreaseCapacity, "#apply" do
it "should decrease capacity by one" do
player = double()
player.should_receive(:capacity) # reads the capacity
player.should_receive(:capacity=) # decrement by one
subject.apply player
end
end

失败信息

1) DecreaseCapacity#apply should decrease the player's capacity by one
Failure/Error: subject.apply player
undefined method `-' for nil:NilClass
# ./item.rb:39:in `apply'
# ./item_spec.rb:25

这是怎么回事?为什么 player.capacity -= 1 试图在 nil 上调用 -

最佳答案

问题在于,当调用 capacity 时,您对播放器进行 stub 的方式将返回 nil。你需要这样改变:

player.should_receive(:capacity).and_return(0)
player.should_receive(:capacity=).with(1)

要了解原因,让我们分解一下您的代码中发生的事情。如果我们将 -= 扩展为:

会更容易看到问题
player.capacity = player.capacity - 1

有了你 stub 的播放器,它就变成了这样:

player.capacity = nil - 1

这正是 RSpec 所提示的。

现在,让我建议一种更好的编写测试的方法。您的测试只是反射(reflect)您的实现,它不测试方法。我的意思是,它不会测试 apply 方法是否将玩家的容量递增一个 - 它会测试 apply 调用 capacity 然后是 capacity=。您可能认为这是同一件事,但这只是因为您知道如何实现该方法。

这就是我编写测试的方式:

it "increments a player's capacity" do
player = Player.new # notice that I use a real Player
player.capacity = 0
subject.apply(player)
player.capacity.should == 1
end

我使用了一个真正的 Player 对象而不是设置一个 stub ,因为我假设 Player#capacity 的实现只是一个访问器,里面没有逻辑干扰我的考试。使用 stub 的风险在于,有时 stub 比真实对象更复杂(我认为在这种情况下),这意味着您的测试更有可能是错误的,而不是您的实际代码。

如果你想使用 RSpec 的完整表现力,你也可以这样写测试:

it "increments a player's capacity" do
player = Player.new
player.capacity = 0
expect { subject.apply(player) }.to change { player.capacity }.to(1)
end

关于ruby - RSpec 模拟失败 "undefined method ` -' for nil:NilClass",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4505665/

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