我第一次使用RSpec创建一个扑克游戏,卡片,甲板,手,玩家,和游戏课程。我已经完成了Card,Deck和&手测试/课程,我正在编写播放器测试/课程。随着依赖关系的增长,它变得越来越难以依赖于模拟/存根而且我遇到了一个问题,我的Player#discard方法测试正在抛出错误,因为RSpec引发了这个错误:
1) Player#discard discards the chosen card
Failure/Error: player.discard
Double "hand" received unexpected message :delete_if with (no args)
# ./lib/player.rb:19:in `block in discard'
# ./lib/player.rb:18:in `each'
# ./lib/player.rb:18:in `discard'
# ./spec/player_spec.rb:34:in `block (3 levels) in <top (required)>'
我是RSpec&amp;的新手不确定我做错了什么。任何帮助&amp;关于如何避免在我的规范中使用实际的类对象使它们通过的建议将非常感激。这是我的player_spec&amp;到目前为止的球员级别。
./规格/ player_spec.rb
require 'rspec'
require 'player'
describe Player do
subject(:player) { Player.new }
its(:hand) { double("hand", :cards => []) }
its(:pot) { should eq 1000 }
let(:ace_spades) { double("card", :suit => :spades, :value => :ace) }
let(:ace_clubs) { double("card", :suit => :clubs, :value => :ace) }
let(:king_spades) { double("card", :suit => :spades, :value => :king) }
let(:king_clubs) { double("card", :suit => :clubs, :value => :king) }
let(:queen_spades) { double("card", :suit => :spades, :value => :queen) }
let(:queen_clubs) { double("card", :suit => :clubs, :value => :queen) }
let(:jack_spades) { double("card", :suit => :spades, :value => :jack) }
let(:jack_clubs) { double("card", :suit => :clubs, :value => :jack) }
let(:ten_spades) { double("card", :suit => :spades, :value => :ten) }
let(:ten_clubs) { double("card", :suit => :clubs, :value => :ten) }
let(:nine_spades) { double("card", :suit => :spades, :value => :nine) }
let(:nine_hearts) { double("card", :suit => :hearts, :value => :nine) }
let(:nine_clubs) { double("card", :suit => :clubs, :value => :nine) }
let(:nine_diamonds) { double("card", :suit => :diamonds, :value => :nine) }
let(:discard_hand) do
double("hand", :cards => [nine_clubs, ace_spades, nine_hearts, ten_clubs, ten_spades])
end
let(:discard_input) { ["A","S"] }
describe "#discard" do
it "discards the chosen card" do
player.hand.stub(:cards).and_return(discard_hand)
player.stub(:get_input).and_return(discard_input)
player.discard
expect(player.hand.cards).to eq([nine_clubs, nine_hearts, ten_clubs, ten_spades])
end
end
end
./ LIB / player.rb
class Player
INPUT_VALUES = { "2" => :deuce, "3" => :three, "4" => :four,
"5" => :five, "6" => :six, "7" => :seven,
"8" => :eight, "9" => :nine, "10" => :ten,
"J" => :jack, "Q" => :queen, "K" => :king, "A" => :ace }
INPUT_SUITS = { "S" => :spades, "H" => :hearts, "C" => :clubs, "D" => :diamonds }
attr_accessor :pot, :hand
def initialize
@pot = 1000
@hand = Hand.new
end
def discard
discards = get_input("Which card(s) would you like to discard?:")
discards.each do |discard|
self.hand.cards.delete_if do |card|
card.value == discard[0] && card.suit == discard[1]
end
end
end
private
def get_input(prompt)
puts prompt
input = gets.chomp
parse_input(input)
end
def parse_input(input)
value = input.scan(/^(?:[2-9]|10|[jqkaJQKA])/)
suit = input.scan(/[shdcSHDC]$/)
raise "Invalid Input" if values.empty? || suit.empty?
(value[0].match(/[jqkaJQKA]/)) ? value[0].upcase! : value.map!(&:to_i)
suit[0].upcase!
value = INPUT_VALUES[value[0]]
suit = INPUT_SUITS[suit[0]]
[value, suit]
end
end
答案 0 :(得分:1)
您收到的错误是因为您正在拨打的代码(即discard
)正在您的某个双打中调用delete_if
。 #39;设定一个允许的期望。您应该查看stub_chain
作为实现此目标的方法。
但更一般地说,我认为您遇到了麻烦,因为您要求Player
丢弃方法通过直接操作卡片阵列来实现删除功能,而不是委托{{ 1}}到discard
。如果您可以简化代码,它将简化您的测试。