RSpec如何允许并期望为多个调用产生意外结果

时间:2014-08-28 14:32:50

标签: ruby rspec expectations

我试图写一个测试,以防止你做两次相同的事情(在这种情况下,在tictactoe中在同一个方块上玩两次),但是RSpec语法令我感到困惑,我无法做到在他们的文档中看到一个解决方案。我尝试了一些没有成功的方法,这让我意识到我并不理解RSpec语法。

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

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

  

def your_turn

your_turn unless play_on(square_at(get_row, get_square))
     

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

在这种情况下,我正在测试一个模块,其中,your_turn,get_row和get_square是该模块的方法,但是play_on和square_at是它集成到的类中的方法,所以我必须在必要时进行存根(与获取方法相同,因为我不想得到RSpec的提示)。

我尝试的第一个测试就是:

  如果玩家无法在该广场上玩,那么它会重复这个过程。'做

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

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

human.your_turn
     

测试失败,并表示只收到一次。我希望这个展开的方式是在最初的your_turn调用中,RSpec将存根play_on,返回nil,设置除非语句并重复your_turn调用 - 之后它将返回一个符号并阻止任何进一步的递归。我误解了什么?

经过那么努力,我想出了一个似乎有用的怪物,但我不完全确定原因:

  

允许(人类)。接收(:get_row).and_return(1,2)

     

允许(人类)。接收(:get_square).and_return(2,2)

     

允许(人类)。接收(:square_at).with(1,2).and_return(:nil)

     

允许(人类)。接收(:square_at).with(2,2).and_return(:square)

     

允许(人类)。接收(:play_on).with(:square).and_return(:square)

     

期待(人类)。接收(:play_on).twice

     

human.your_turn

这里的麻烦(除了这个丑陋之外)是我通过暴力而不是理解来使它更有效,而且还有一些我不确定的事情:

  • 为什么我不能删除例如前两行没有提示返回RSpec?因为在第三行和第四行我捏造方法square_at,它会调用get_方法,为什么它们仍被调用?
  • 同样,第五行第三和第四行似乎涵盖了第三和第四行,但我最初的最后一次允许'允许' return(nil,:square),期待这个工作。最后调用your_turn三次,我期待两次,所以我删除了零,它通过了。我解析它的方式,没有nil,play_on将立即返回:square,所以除非逻辑不被触发,否则方法将终止。我又误解了什么?
  • 是否有一种干燥方式来处理两个' square_at'允许线?

全心全意,

萨莎

1 个答案:

答案 0 :(得分:0)

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

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