2017-08-14 90 views
0

我有以下代码(国际象棋的实现,我经历theodinproject.com路径):最好的测试方法的方法从初始化运行使用RSpec

class Move 
def initialize(player, board) 
    @player  = player 
    @board  = board 
    @from  = ask_for_move_details("from") 
    @from_sq = @board[@from.to_sym] 
    @from_piece = @from_sq[:piece] 
    @to   = ask_for_move_details("to") 
    @to_sq  = @board[@to.to_sym] 
    make_a_move if move_allowed? 
end 

def ask_for_move_details(from_or_to) 
    begin 
    msg_ask_for_move_details(@player, from_or_to) 
    chosen_address = gets.chomp.to_s 
    raise unless address_valid?(chosen_address) 
    rescue 
    msg_move_not_allowed 
    retry 
    end 
    chosen_address 
end 
... 
end 

我需要测试其运行时ask_for_move_details("from"/"to")方法对象实例正在创建中。

目标是例如使@from变量得到值"a1"@to变量得到"a6"值。到目前为止,我想出了只有这个:

allow(Move).to receive(:gets).and_return("a1", "a6") 

,但它不工作,因为@from得到零值,测试失败。

我知道初始化方法根本不应该被测试,但是这种情况使得不可能创建对象的实例并因此测试它的方法。我应该重构代码吗?

回答

0

ask_for_move_details("from"/"to")可以使用allow_any_instance_ofwith残留。

例如:

class A 
    def a(b) 
    end 
end 

describe do 
    before do 
    allow_any_instance_of(A).to receive(:a).with(1) { 2 } 
    allow_any_instance_of(A).to receive(:a).with(2) { 3 } 
    end 

    it do 
    expect(A.new.a(1)).to eq 2 
    expect(A.new.a(2)).to eq 3 
    end 
end 

所以,通过ask_for_move_details返回值可以根据传递给此方法的参数存根:

allow_any_instance_of(Move).to receive(:ask_for_move_details).with("from") { "a1" } 
allow_any_instance_of(Move).to receive(:ask_for_move_details).with("to") { "a6" } 
+0

这工作!非常感谢 :) – sloneorzeszki