ruby - RSpec 如何允许和期望多次调用产生意外结果

标签 ruby rspec expectations

我正在尝试编写一个测试来防止你做同样的事情两次(在这种情况下,在 tictactoe 中在同一个方 block 上玩两次),但是 RSpec 语法让我感到困惑,我看不到解决方案他们的文档。我尝试了几种方法都没有成功,这让我意识到我并不像我想的那样理解 RSpec 语法。

因为测试是针对递归方法的,所以很多错误都没有我想要的那样具有描述性,因为它们会导致程序崩溃,这使得很难隔离问题。

我尝试测试/创建的方法最初看起来像这样:

def your_turn

your_turn unless play_on(square_at(get_row, get_square))

end

(如果没有成功放置标记,play_on 返回 nil)

在这种情况下,我正在测试一个模块,your_turn、get_row 和 get_square 是该模块的方法,但是 play_on 和 square_at 是它要集成到的类中的方法,所以我在必要的地方 stub (同上get 方法,因为我不想收到 RSpec 的提示)。

我尝试的第一个测试是这样的:

it 'repeats the process if a player can't play on that square' do

allow(human).to receive(:play_on).and_return(nil, :square)

expect(human).to receive(:your_turn).twice

human.your_turn

end

测试失败,并表示只收到一次。我期望它展开的方式是在最初的 your_turn 调用中,RSpec 将对 play_on 进行 stub ,返回 nil,触发 unless 语句并重复 your_turn 调用——之后它将返回一个符号并阻止任何进一步的递归。我误解了什么?

经过努力,我想出了一个似乎可行的怪物,但我不完全确定为什么:

allow(human).to receive(:get_row).and_return(1,2)

allow(human).to receive(:get_square).and_return(2,2)

allow(human).to receive(:square_at).with(1, 2).and_return(:nil)

allow(human).to receive(:square_at).with(2, 2).and_return(:square)

allow(human).to receive(:play_on).with(:square).and_return(:square)

expect(human).to receive(:play_on).twice

human.your_turn

这里的问题(除了丑陋之外)是我通过蛮力而不是理解让它工作更多,并且有几件事我不确定:

  • 为什么我不能在没有返回 RSpec 提示的情况下删除前两行?由于在第三行和第四行我将调用 get_ 方法的方法 square_at stub ,为什么它们仍然被调用?
  • 类似地,第五行第三行和第四行似乎覆盖了第三行和第四行,但我最初有最后一个“允许”return(nil, :square),希望它能工作。最终调用了 your_turn 三次,而我期望调用两次,所以我删除了 nil 并且它通过了。我解析它的方式,如果没有 nil,play_on 将立即返回 :square,因此不会触发 unless 逻辑并且该方法将终止。再一次,我误解了什么?
  • 是否有更简洁的方法来处理两条“square_at”允许线?

谢谢大家

萨沙

最佳答案

我不明白你的问题(特别是第二个和第三个),但我相信你的问题的很大一部分是认为仅仅因为你 stub 了一个方法调用,Ruby 就不会评估方法调用参数。

get_rowget_square 方法在square_at 之前被调用。 Ruby 从“右到左”“解析”语句,因此它首先调用 get_row,然后调用 get_square,最后调用 square_at 传递两者的结果get_ 方法。这可能会破坏您的测试,具体取决于这两种方法的作用,并解释了为什么您需要前两个 stub 。

关于ruby - RSpec 如何允许和期望多次调用产生意外结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25551421/

相关文章:

ruby - 如何从 Jekyll 插件中调用 `handleize` Liquid 过滤器?

Ruby 紧凑的赋值语法

ruby - 检查变量是否为整数

ruby - 从 'within' block 中引用外部节点

ruby-on-rails - RSpec,期望随着多个值的变化而变化

ruby - Mocha 预计最多一次,调用两次,但方法显然只调用一次

c++ - Hippomock 的 MockRepository::BasicRegisterExpect 中的 NotImplementedException

ruby-on-rails - 直接在模型上调用 rspec 会导致 stub 错误!方法

ruby-on-rails - 如何在没有关联数据库表的情况下 RSpec 共享 ActiveRecord 模块?

mocking - 具有多个 Expects() 调用的 PHPUnit 模拟