如何依赖测试主题?

时间:2012-02-09 19:44:23

标签: ruby unit-testing rspec mocking tdd

我想用Ruby开发基于卡片的游戏,我想以 TDD 的方式进行游戏。

我想写的第一堂课是 Player 。 每位玩家拥有13张牌的,并且在他/她的回合中可以选择并玩1张牌来传递。

我还没有开发过任何其他类(比如card,hand,..),我想知道如何测试这个依赖于其他类的主题?

我知道Mocks但我不知道如何使用它们。

例如,在这种情况下,我们知道当玩家时,一张卡片必须从他/她的手中取出。

这是我的代码:

require "rspec"
require "lib/player"

describe Player do
  before(:each) do
    hand=mock("Hand")
    hand.should_receive(:count).and_return(13)
    subject.hand=hand
  end

  it "should choose and play a card from her/his hand" do
      subject.hand.count.should==13
      card_selected=subject.play(2)      # card #2 in his/her hand
      subject.hand.count.should=12
   end
end

另外,在实现中我们依赖于Hand类,我该如何处理它?<​​/ p>

1 个答案:

答案 0 :(得分:2)

我已经看到了我的嘲讽和抄袭,我已经看到了大量的测试套件通过,即使应用程序被打破了,因为一半的代码甚至不再存在。

我得出的结论是,应该非常谨慎地使用剔除和嘲弄。那个,以及它应该尽可能晚地介绍的事实。

这是嘲笑为时尚早的案例之一。你只是因为你还没有上课Hand而嘲笑。

作为旁注,测试本身需要改进。仔细看看这些内容:

hand.should_receive(:count).and_return(13)
subject.hand=hand
subject.hand.count.should==13
subject.hand.count.should=12

当然,subject.hand.count.should==13通过,你只是将它存根到这个值。当然,subject.hand.count.should=12通过,因为您没有致电==。如果你把它改成了真正的期望,你会想知道为什么它会失败。它失败了,因为您将Hand#count存根到总是返回13。

你在这里做的是模拟被测API的一部分。不要这样做。相反,从婴儿步骤开始。这可能意味着:

  • 你从内心开始,逐步解决问题。所以从这个案例中最内层的类Hand开始。一旦你到达Player,所有的部分都会很好地融合在一起而不会嘲笑。

  • 您从Player 开始,直到您绝对需要其他类(如果“有意义的API”的参数吸引您,请执行此操作)。这意味着:在NameError上等待Hand。然后根据需要实现尽可能多的Hand类。然后返回Player

另外,查看你的代码提出了一个问题:出于好奇,你为什么要首先将玩家和她的手分开?