# How to catch the mocked infinite loop behavior and handle it with a rescue block using RSpec

**URL:** <https://www.ruby-forum.com/t/how-to-catch-the-mocked-infinite-loop-behavior-and-handle-it-with-a-rescue-block-using-rspec/235868>\
**Category:** RSpec\
**Created:** [July 20, 2013, 7:19pm UTC](https://www.ruby-forum.com/t/how-to-catch-the-mocked-infinite-loop-behavior-and-handle-it-with-a-rescue-block-using-rspec/235868 "2013-07-20T19:19:37Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![alcina](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a587f6/32.png) [@alcina](https://www.ruby-forum.com/u/alcina)\
**Post date:** [July 20, 2013, 7:19pm UTC](https://www.ruby-forum.com/t/how-to-catch-the-mocked-infinite-loop-behavior-and-handle-it-with-a-rescue-block-using-rspec/235868/1 "2013-07-20T19:19:37Z")

</div>

I have a Book Model which is a ruby script that assigns prices to  
certain predefined Book titles mentioned in the program. I’m using Ruby  
1.9.3-p327 and rspec 2.11.0

```
#class RspecLoopStop < Exception; end
class Book

  attr_accessor :books
  def initialize books
    puts "Welcome to setting book price program"
    @books = books
  end

  def get_prices
    puts "Please enter appropriate price for each book item:-"
    count = 0
    @books = @books.inject({}) { |hash, book|
      print "#{book.first}: "
      price = STDIN.gets.chomp
      while (price !~ /^[1-9]\d*$/ && price != "second hand")
        puts "Price cannot be 0 or a negative integer or in decimal

```

format or alphanumeric. \nPlease input appropriate duration in integer"  
price = STDIN.gets.chomp #gets.chomp - throws error  
end  
price == “second hand” ? price = “100” : price #takes a  
default price  
hash[book.first] = price.to\_i  
hash  
}  
end

```
end

books = {"The Last Samurai" => nil,
         "Ruby Cookbook" => nil,
         "Rails Recipes" => nil,
         "Agile Development with Rails" => nil,
         "Harry Potter and the Deathly Hallows" => nil}

book_details = Book.new(books)
book_details.get_prices
#puts "\n *******Books:#{book_details.books}****** \n"

```

If a user inputs any alphanumeric data or negative number or 0 or  
anything having decimals, as per the program the user is asked to enter  
only a positive integer for the price of each book. I’ve tried to mock  
this behavior using RSpec.

My current challenge is how to catch the wrong user input, the message  
that comes along with and handle it appropriately so that the spec  
should pass. I’ve tried a couple of things but the below spec currently  
runs into an infinite loop with input price given in the wrong format.  
PFB my spec.

```
require 'spec_helper'

describe Book do

  before :each do
    books = {"The Last Samurai" => nil,
         "Ruby Cookbook" => nil,
         "Rails Recipes" => nil,
         "Agile Development with Rails" => nil,
         "Harry Potter and the Deathly Hallows" => nil}
    @book = Book.new(books)
  end

  describe "#getprice" do
    it "Should get the price in the correct format or else return

```

appropriate error" do  
puts  
“\n\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\n”  
book\_obj = @book  
STDIN.stub(:gets) { “40” }  
book\_obj.get\_prices.should\_not be\_nil  
end

```
    it "Incorrect input format should return error message asking

```

user to re input" do  
puts  
“\n\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\n”  
book\_obj = @book  
#STDIN.stub(:gets) { “40abc” }

```
      #book_obj.get_prices.should be_nil --> adding this line of

```

code goes into an infinite loop with the error message below  
#Price cannot be 0 or a negative integer or in decimal format  
or alphanumeric. \nPlease input appropriate duration in integer\n

```
      #STDOUT.should_receive(:puts).and_return("Price cannot be 0 or

```

a negative integer or in decimal format or alphanumeric. \nPlease input  
appropriate duration in integer\n")

```
      #the below two tests fails with syntax error - don't seem that

```

easy to figure out what’s going wrong

```
      #STDOUT.should_receive("Price cannot be 0 or a negative

```

integer or in decimal format or alphanumeric. \nPlease input appropriate  
duration in integer\n")  
#\n towards the end is as in the third line of input the user  
is asked to re enter input in correct format  
#STDOUT.should == “Price cannot be 0 or a negative integer or  
in decimal format or alphanumeric. \nPlease input appropriate duration  
in integer\n”

```
      #begin #didn't work for me
      # STDIN.stub(:gets) { "40abc" }
      # book_obj.get_prices.should_raise RspecLoopStop
      #rescue RspecLoopStop
      # #exit
      #end

      begin
        STDIN.stub(:gets) { "40abc" } #incorrect input prompts user

```

to re enter price in correct format  
book\_obj.get\_prices #how to catch the infinite loop as an  
exception and exit out of it say using rescue block  
rescue #I guess this won’t be called until the exception is  
correctly caught  
STDIN.stub(:gets) { “85” }  
book\_obj.get\_prices.should\_not be\_nil  
end

```
    end
  end

end

```

Can anyone please point me in the right direction on how can I handle  
this correctly. I’m able to mock the user being asked to re enter data  
for wrong input. My question is how can I stop that(as per the actual  
program logic) upon correct input as part of the spec.

I did try one of the suggestions from [a similar question](http://stackoverflow.com/questions/5717813/what-is-the-best-practice-when-it-comes-to-testing-infinite-loops), but it  
doesn’t seem to be working for me. I could be missing something. The

[code](https://github.com/boddhisattva/book.git) is also available to be cloned from Github. Thank you.
