Как проверить предмет с зависимостью? - PullRequest
3 голосов
/ 09 февраля 2012

Я хочу разработать карточную игру на Ruby и TDD .

Первый класс, который я хочу написать, - Player .У каждого игрока есть рука с 13 картами, и в свой ход он может выбрать и разыграть 1 карту для прохождения.

Я не разработал никаких других классов (таких как карта, рука, ..), Я хочу знать, как я могу проверить этот предмет, который имеет зависимость от других классов?

Я знаю о 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, как я могу его обработать?

1 Ответ

2 голосов
/ 21 марта 2012

Я видел свою долю насмешек и заглушек, и я видел, как проходили огромные тестовые наборы, хотя приложение было сломано до предела, потому что половина кода даже больше не существовала.

I 'Мы пришли к выводу, что заглушки и насмешки следует использовать с особой осторожностью.Это и тот факт, что это должно быть введено как можно позже.

Это один из случаев, когда слишком рано издеваться. Вы издеваетесь только потому, что вы этого не делаетеиметь класс 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

Кроме того, просмотр вашего кода поднимает вопрос: просто из любопытства, почему вы хотите разделить игрока и ее руку в первую очередь?

...