Note that there are some explanatory texts on larger screens.

plurals
  1. PORSpec can't define singleton error when trying to mock gets and puts for Hash Elements
    primarykey
    data
    text
    <p>I have a Book Model which is a ruby script that assigns prices to certain predefined Book titles mentioned in the program. Here's how the book model looks:-</p> <pre><code>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*$/ &amp;&amp; price != "second hand") puts "Price can't be 0 or a negative integer or in decimal format or alphanumeric. \nPlease input appropriate price 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" =&gt; nil, "Ruby Cookbook" =&gt; nil, "Rails Recipes" =&gt; nil, "Agile Development with Rails" =&gt; nil, "Harry Potter and the Deathly Hallows" =&gt; nil} book_details = Book.new(books) book_details.get_prices puts "\n*******Books Details:#{book_details.books}******\n" </code></pre> <p>I'm trying to write a test case that checks for correct input of price for each book item. If the price is entered inappropriately, it should ask the user to re enter the price correctly. The program does this fine. But I'm facing difficulties when I'm trying to mock this behavior using RSpec. </p> <pre><code>require 'spec_helper' describe Book do before :each do books = {"The Last Samurai" =&gt; nil, "Ruby Cookbook" =&gt; nil, "Rails Recipes" =&gt; nil, "Agile Development with Rails" =&gt; nil, "Harry Potter and the Deathly Hallows" =&gt; nil} @book = Book.new(books) end describe "#new" do it "Should be an instance of the Book" do @book.should be_an_instance_of Book end 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 STDOUT.should_receive(:puts).and_return("Welcome to setting book price program") book_obj.get_prices.should_not be_nil book_obj.books["The Last Samurai"].stub!(:gets) {"40"} #trying to set the value for one book using Hash book_obj.books["The Last Samurai"].should == 40 #verifying the value set for a particular key is accurate end end end </code></pre> <p>You can even <a href="https://github.com/boddhisattva/book" rel="nofollow">clone this code</a> from Github to try this from your end. I'm using Ruby 1.9.3 and rspec 2.11.0</p> <pre><code>The error that I'm getting currently is:- Failures: 1) Book#getprice Should get the price in the correct format or else return appropriate error Failure/Error: book_obj.books["The Last Samurai"].stub!(:gets) {"40"} #trying to set the value for one book using Hash TypeError: can't define singleton # ./spec/book_spec.rb:31:in `block (3 levels) in &lt;top (required)&gt;' Finished in 7.61 seconds 2 examples, 1 failure Failed examples: rspec ./spec/book_spec.rb:21 # Book#getprice Should get the price in the correct format or else return appropriate error </code></pre> <p><strong>UPDATED QUESTION</strong></p> <p>For <em>bad user input</em>, with the below test case I'm getting the following error. How can I correctly handle this? I've tried a couple of options, but they all seem to fail. Please see the comment for each option as part of the spec snippet.</p> <pre><code> 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 --&gt; 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") #STDOUT.should == "Price cannot be 0 or a negative integer or in decimal format or alphanumeric. \nPlease input appropriate duration in integer\n" end Failures: 1) Book#getprice Incorrect input format should return error message asking user to re input Failure/Error: 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") (#&lt;IO:0x00000001c7b298&gt;).puts(any args) expected: 1 time received: 0 times # ./spec/book_spec.rb:40:in `block (3 levels) in &lt;top (required)&gt;' </code></pre> <p>I would really appreciate any guidance how to get this right. Thank you.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload