How to test Ruby methods that involve puts or gets

Last updated 93 days ago by Jason Swett

ruby

I recently saw a post on Reddit where the OP asked how to test a method which involved puts and gets. The example the OP posted looked like the following (which I’ve edited very slightly for clarity):

``` class Example def askfornumber puts "Input an integer 5 or above" loop do input = gets.to_i return true if input >= 5 puts "Invalid. Try again:" end end end

```

``` class Example

def askfornumber

puts "Input an integer 5 or above"

loop do

  input = gets.to_i

  return true if input >= 5

  puts "Invalid. Try again:"

end

end

end

```

What makes the ask_for_number method challenging to test is a dependency. Most methods can be tested by saying, “When I pass in argument X, I expect return value Y.” This one isn’t so straightforward though. This is more like “When the user sees output X and then enters value V, expect subsequent output O.”

Instead of accepting arguments, this method gets its value from user input. And instead of necessarily returning a value, this method sometimes simply outputs more text.

How can we give this method the values it needs, and how can we observe the way the method behaves when we give it these values?

Test doubles can help us

The answer is to use test doubles. Like a stunt double, a test double is an object that stands in the place of a “real” object and provides some special behaviors. I’ll provide an example below because I think some code will be clearer than words.

Let’s say that I first want to write a test that says:

  1. When ask_for_number is first called, expect that it prompts us with Input an integer 5 or above
  2. When I respond to that prompt with a value of 6, expect that ask_for_number returns true (because 6 is greater than or equal to 5)

Here are those steps translated into RSpec.

Read full Article