2014-12-13 44 views
2

我有一个要求用户输入的代码,如:“在哪里?foobar的”rspec的3错误时,系统会提示用户输入

class Foo 
    def prompt_for_foobar 
    puts "where is the foobar?" 
    gets.chomp 
    end 
end 

我想测试我的应用程序要求。我的测试将通过评论'gets.chomp'。但是这是必要的,而我尝试过的其他东西都给了我一个Errno :: ENOENT:错误。

it "should prompt user" do 
    console = Foo.new 
    request = "where is the foobar?" 
    expect { console.prompt_for_foobar }.to output(request).to_stdout 
end 

测试此方法的最佳方法是什么?

+0

此概念的可能重复:http://stackoverflow.com/questions/16948645/how-do-i-test-a-function-with-gets-chomp-in-it – joelparkerhenderson 2014-12-13 01:11:43

回答

0

不知道这是否是处理此问题的最佳方法,但您可以发送putsgetsSTDOUTSTDIN

class Foo 
    def prompt_for_foobar 
    STDOUT.puts "where is the foobar?" 
    STDIN.gets.chomp 
    end 
end 

然后,测试STDIN接收puts消息与期望的对象。

describe Foo do 
    let(:foo) { Foo.new } 

    before(:each) do 
    allow(STDIN).to receive(:gets) { "user input" } 
    end 

    describe "#prompt_for_foobar" do 
    it "prompts the user" do 
     expect(STDOUT).to receive(:puts).with("where is the foobar?") 

     foo.prompt_for_foobar 
    end 

    it "returns input from the user" do 
     allow(STDOUT).to receive(:puts) 

     expect(foo.prompt_for_foobar).to eq "user input" 
    end 
    end 
end 
0

的问题是,gets是迫使人类交互(在RSpec的,其中标准输入不从另一个进程连接到管道的上下文中至少)的方法,但自动化测试工具的整个点像RSpec一样能够在不涉及人机交互的情况下运行测试。

因此,我建议您不要直接依赖gets来实现特定的接口 - 这种方式在测试环境中可以提供该接口的实现,该接口不提供响应人与人之间的互动,并且在其他环境中,它可以使用gets来提供响应。这里最简单的合作者界面可能是一个进程(他们是完美的这种事情!),所以你可以做到以下几点:

class Foo 
    def prompt_for_foobar(&responder) 
    responder ||= lambda { gets } 
    puts "where is the foobar?" 
    responder.call.chomp 
    end 
end 

RSpec.describe Foo do 
    it 'prompts the user to respond' do 
    expect { Foo.new.prompt_for_foobar { "" } }.to output(/where is the foobar/).to_stdout 
    end 

    it "returns the responder's response" do 
    expect(Foo.new.prompt_for_foobar { "response" }).to eq("response") 
    end 
end 

注意prompt_for_foobar不再直接调用gets;相反,它代表负责获得对协作者的回复。默认情况下,如果未提供响应者,则使用gets作为响应者的默认实现。在你的测试中,你可以简单地通过传递一个返回字符串的块来提供一个不需要人工交互的响应者。