プログラムで言及されている特定の事前定義された本のタイトルに価格を割り当てるルビ スクリプトである本モデルがあります。本のモデルは次のようになります。
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"
各書籍アイテムの価格が正しく入力されているかどうかをチェックするテスト ケースを作成しようとしています。価格が不適切に入力された場合は、ユーザーに価格を正しく再入力するように求める必要があります。プログラムはこれをうまく行います。しかし、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
Github からこのコードを複製して、自分の側からこれを試すこともできます。Ruby 1.9.3 と rspec 2.11.0 を使用しています
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
更新された質問
悪いユーザー入力の場合、以下のテストケースで次のエラーが発生します。どうすればこれを正しく処理できますか? いくつかのオプションを試しましたが、すべて失敗しているようです。仕様スニペットの一部として、各オプションのコメントを参照してください。
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")
#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")
(#<IO:0x00000001c7b298>).puts(any args)
expected: 1 time
received: 0 times
# ./spec/book_spec.rb:40:in `block (3 levels) in <top (required)>'
これを正しく行う方法についてのガイダンスをいただければ幸いです。ありがとうございました。