У меня есть модель книги, которая представляет собой рубиновый скрипт, который присваивает цены определенным предопределенным названиям книг, упомянутым в программе. Вот как книга выглядит модель: -RSpec не может определить одноэлементную ошибку при попытке подделать get и put для хэш-элементов
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
Вы можете даже clone this code от 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)>'
Я бы очень признателен за любые рекомендации, как правильно это сделать. Спасибо.
Прежде всего, очень признателен, что вы пытаетесь помочь мне обойти это. Ваше предложение действительно помогло обработать ввод данных пользователя в правильном формате. Я по-прежнему не в состоянии понять, что происходит с плохим пользовательским вводом, пытаясь попробовать пару комбинаций (см. ** обновленный вопрос ** с информацией о коде и ошибке). У меня просто есть еще одна вещь, чтобы спросить, пожалуйста, извините мое невежество, если я что-то упустил .. при попытке заглушки заходит на book_obj.books [«Последний самурай»] Я просто пытаюсь присвоить значение ключу, поэтому я действительно не понимаю, что там int .. пожалуйста, объясните .. Спасибо. – boddhisattva
Бесконечный цикл из-за цикла while в 'get_prices'. Вам нужно будет заглушить как плохой ввод, так и хороший ввод, чтобы пройти мимо этого, например. 'STDIN.stub (: получает) {" 40abc "}; STDIN.stub (: получает) {"40"}; '. –
Синтаксическая ошибка заключается в том, что вы говорите: «STDOUT» должен получать строку, но она должна получать 'puts' _with_ a String, например. 'STDOUT.should_receive (: puts) .with (" this string ")'. То, что у вас есть, пытается найти метод с именем «Цена» не может быть 0 или отрицательным целым числом или в десятичном формате или буквенно-цифровом. \ NПожалуйста, введите соответствующую продолжительность в integer \ n ", таким образом, синтаксическую ошибку. –