使用 RSpec 用 get 测试用户输入

Sal*_*dec 7 ruby unit-testing rspec

我是使用 RSpec 和 Ruby 进行单元测试的新手,我有一个关于如何测试我的代码是否使用该gets方法但不提示用户输入的问题。

这是我要测试的代码。这里没什么疯狂的,只是一个简单的一个班轮。

我的文件.rb

My_name = gets
Run Code Online (Sandbox Code Playgroud)

这是我的规格。

require 'stringio'

def capture_name
    $stdin.gets.chomp
end

describe 'capture_name' do
    before do
        $stdin = StringIO.new("John Doe\n")
    end

    after do 
        $stdin = STDIN
    end

    it "should be 'John Doe'" do 
        expect(capture_name).to be == 'John Doe'
        require_relative 'my_file.rb'
    end
end
Run Code Online (Sandbox Code Playgroud)

现在这个规范有效,但是当我运行代码时,它会提示用户输入。我不希望它这样做。我想简单地测试是否正在调用获取方法并可能模拟用户输入。不确定如何在 RSpec 中实现这一点。在 Python 中,我会使用unittest.mock在 RSpec 中是否有类似的方法?

提前致谢!

Nab*_*eel 8

这是您如何gets使用返回值存根的方法。

require 'rspec'

RSpec.describe do
  describe 'capture_name' do
    it 'returns foo as input' do
      allow($stdin).to receive(:gets).and_return('foo')
      name = $stdin.gets

      expect(name).to eq('food')
    end
  end
end

Failures:

  1)   should eq "food"
     Failure/Error: expect(name).to eq('food')

       expected: "food"
            got: "foo"

       (compared using ==)
Run Code Online (Sandbox Code Playgroud)

要测试是否正在调用某些东西(例如函数),您可以使用expect($stdin).to receive(:gets).with('foo')它来确保使用正确的参数调用它(一次)。在这个场景中的期望线必须在 之前name = $stdin.gets