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:-


    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 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" => 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 Details:#{book_details.books}******\n"


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.

    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 "#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


You can even clone this code(https://github.com/boddhisattva/book) from
Github to try this from your end. I'm using Ruby 1.9.3 and rspec 2.11.0.
I've also attached all the required ruby scripts in this forum post to
test this.





    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 <top
(required)>'

    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


I would really appreciate any guidance how to get this right. Thank you.

Attachments:
http://www.ruby-forum.com/attachment/8625/book.rb
http://www.ruby-forum.com/attachment/8626/book_spec.rb
http://www.ruby-forum.com/attachment/8627/spec_helper.rb


-- 
Posted via http://www.ruby-forum.com/.
_______________________________________________
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users

Reply via email to