【问题标题】:Testing gets in rspec (user input)测试进入 rspec(用户输入)
【发布时间】:2018-11-28 19:56:32
【问题描述】:

我的班级有这个 #run 方法,到目前为止就是这样,用于测试测试:

def run
    puts "Enter 'class' to create a new class."
    input = $stdin.gets.chomp
    binding.pry

在目前的测试中,我得到了

  allow($stdin).to receive(:gets).and_return 'class'
  cli.run

这样做我可以在 pry 会话中看到 input 已按预期设置为 'class'

有没有办法在我的方法本身中不将$stdin 添加到我对gets 的调用中?即input = gets.chomp

我试过allow(cli.run).to receive(:gets).and_return 'class' 但随后在 pry session 中,input 等于 spec 文件的第一行!

【问题讨论】:

    标签: ruby rspec mocking


    【解决方案1】:

    你可以这样避免:

    def run
      puts "Enter 'class' to create a new class."
      input = gets.chomp
    end
    
    describe 'gets' do 
      it 'belongs to Kernel' do 
        allow_any_instance_of(Kernel).to receive(:gets).and_return('class')
        expect(run).to eq('class')
      end
    end
    

    方法gets实际上属于Kernel模块。 (method(:gets).owner == Kernel)。由于Kernel 包含在Object 中,并且几乎所有的ruby 对象都继承自Object,这将起作用。

    现在,如果 runClass 范围内的实例方法,我建议将存根的范围扩大一点:

    class Test
      def run
        puts "Enter 'class' to create a new class."
        input = gets.chomp
      end
    end
    
    describe 'gets' do 
      it 'can be stubbed lower than that' do 
        allow_any_instance_of(Test).to receive(:gets).and_return('class')
        expect(Test.new.run).to eq('class')
      end
      # or even 
      it 'or even lower than that' do 
        cli = Test.new
        allow(cli).to receive(:gets).and_return('class')
        expect(cli.run).to eq('class')
      end
    end
    

    Example

    【讨论】:

    • 谢谢! allow(cli).to receive(:gets).and_return('class') 正是我一直在寻找的那种东西,而且它有效。
    猜你喜欢
    • 1970-01-01
    • 2012-12-24
    • 2021-12-25
    • 2014-06-14
    • 2019-10-13
    • 2020-12-17
    • 1970-01-01
    • 2011-09-18
    • 2023-03-17
    相关资源
    最近更新 更多