Using RSpec to test user input with gets

会有一股神秘感。 提交于 2020-01-14 10:32:32

问题


I'm new to Unit Testing using RSpec and Ruby and I have a question on how to test if my code is using the gets method, but without prompting for user input.

Here is the code I'm trying to test. Nothing crazy here, just a simple one liner.

my_file.rb

My_name = gets

Here's my spec.

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

Now this spec works, but when I run the code it prompts for user input. I don't want it to do that. I want to simply test if the gets method is being called and possibly mock the user input. Not to sure how to achieve this in RSpec. In Python I would utilize unittest.mock is there a similar method in RSpec?

Thanks in advance!


回答1:


Here's how you could stub gets with your return value.

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 ==)

To test if something is being called (such as a function) you can use expect($stdin).to receive(:gets).with('foo') to ensure it is being called (once) with the right args. The expectation line in this scenario has to go before name = $stdin.gets.



来源:https://stackoverflow.com/questions/37329190/using-rspec-to-test-user-input-with-gets

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!