2015-11-24 4 views
0

Я пытаюсь протестировать программу, которая имитирует лифт уже два дня с небольшим успехом. Вот мой класс лифта, программа по-прежнему работает, и я также прокомментировал некоторые методы, которые могут быть не важны для теста, с которым у меня возникают проблемы. Я с удовольствием показать больше кода, если вы считаете, что это необходимоНеполадка при правильном запуске тестов

class Elevator 
    attr_accessor :current_floor 

    GROUND = 0 
    TOP = 15 

    def initialize 
    @floors = []     # list of floors to travel to 
    @pending = []     # store floors not in direction of travel 
    @current_floor = GROUND 
    @going_up = true    # cannot travel downward from ground floor 
    @going_down = false 
    end 

    def get_input 
    gets.chomp 
    end 

    def run 
    enter_floors 
    sort_floors 
    move_to_floor 
    end 

    def enter_floors 
    # prompts the user for input and calls check_floor_numbers 
    end 

    def check_floor_numbers floors 
    # calls validate_floors to ensure user entered '2' instead of 'two' 
    # if proper floor numbers have been entered this method adds the number 
    # to @floors array other wise it calls floor_error_message 
    end 

    def floor_error_message 
    puts "Please enter numbers only." 
    enter_floors 
    end 

    def sort_floors 
    # if we are on the ground floor this method sorts @floors in ascending order 
    # if we are on the top floor it sorts @floors in descending order 
    # else it calls check_direction_of_travel 
    end 

    def move_to_floor 
    floor = @floors[0] 

    if @current_floor == floor 
     puts "You are already on floor #{floor}" 
    else 
     print_direction 
     (@current_floor..floor).each { |floor| puts "...#{floor}" } 
     @current_floor = floor   # update current_floor 
     @floors.delete_at(0)    # remove floor from list 
    end 

    check_for_more_passengers 
    end 

    def check_for_more_passengers 
    puts "Are there any more passengers? (Y/N)" 
    answer = (get_input).upcase 

    answer == 'Y' ? run : check_next_move 
    end 

    def check_next_move 
    if @floors.empty? && @pending.empty? 
     end_ride 
    else 
     move_to_floor 
    end 
    end 

    def check_direction_of_travel 
    # not implemented - add floor to appropriate array depending on dir 
    # of travel 
    end 

    def end_ride 
    puts "\n\nEND." 
    end 

    def print_direction 
    msg = " " 
    @going_up ? msg = "Going Up!" : msg = "Going Down!" 
    puts msg 
    end 
end 

Я пытаюсь проверить, что лифт может двигаться к определенному полу. Сначала у меня возникли проблемы с тестированием ввода с консоли без запуска самой программы. I asked a question about this и был отнесен к this answer in a different question. Выбранный ответ выдает gets.chomp на отдельный метод, а затем переопределяет метод в тестах. Я в конечном итоге с чем-то вроде этого:

describe "it can move to a floor" do 
    before do 
     @@moves = ["2", "N"] 
     def get_input; @@moves.next end 
    end 

    it "should move to floor 2" do 
     e = Elevator.new 
     e.run 
     assert_equal(e.current_floor, 2) 
    end 
    end 

Проблема:get_input не было должным образом overidden и запустить тестовый набор запроса пользователя для ввода, так что было предложено, чтобы я open the Elevator class in the test itself для того, чтобы этот метод был правильно переопределен. Попытка сделать это в конечном итоге привело к испытанию, как это:

describe "it can move to a floor" do 
    before do 
     class Elevator 
     attr_accessor :current_floor 
     @@moves = ["2", "N"] 
     def get_input; @@moves.next end 
     def run; end 
     end 
    end 

    it "should move to floor 2" do 
     e = Elevator.new 
     e.run 
     assert_equal(e.current_floor, 2) 
    end 
    end 

мне пришлось переопределить run и добавить attr_accessor для current_floor, потому что я получаю метод недостающих ошибок.

Проблема: Этот тест дает следующее сообщение об ошибке:

1) Failure: it can move to a floor#test_0001_should move to floor 2 [elevator_test.rb:24]: Expected: nil Actual: 2

Я пытался привести в порядок класса Elevator как можно больше и держать методы, как просто, как я мог бы с учетом параметров программа.

Может ли кто-нибудь указать мне в правильном направлении, чтобы решить эту проблему, возможно, с примерами псевдокода (если это возможно), чтобы продемонстрировать, как я должен подходить к этой проблеме, если ответ на рефакторинг.

Пожалуйста, имейте в виду, что я также хотел бы реализовать другие тесты, такие как проверка того, что класс лифта может поддерживать список этажей или что он может изменить направление, в будущем, когда вы ответите.

+0

'@ floors' - пустой массив, и ваш код использует' @floors [0] ', который, как оказалось, равен nil. Ваш код, как показано выше, дает ошибку 'ArgumentError: плохое значение для диапазона' –

+0

Класс лифта отлично работает для меня. Вы хотите, чтобы я включил весь класс без комментариев в github? – SoSimple

+0

Если все в порядке с вами, вы можете поделиться им - и поместите ссылку на этот вопрос выше. –

ответ

0

Ваш тестовый класс ElevatorTest пересматривает Elevator переопределить метод get_input, но он не открывается класс Elevator, определенный в elevator.rb, но вместо этого он является своего рода создание нового класса Elevator который случается быть определен внутри класса ElevatorTest. Помните, что каждый класс также является модулем, поэтому теперь у вас есть новый класс ElevatorTest::Elevator.

Чтобы исправить эту проблему, я внесла некоторые изменения в elevator_test.rb, которые показаны ниже.

gem 'minitest', '>= 5.0.0' 
require 'minitest/spec' 
require 'minitest/autorun' 
require_relative 'elevator' 

class Elevator 
    @@moves = ["2", "N"].each 
    def get_input; @@moves.next end 
end 

class ElevatorTest < MiniTest::Test 
    def test_working 
    assert_equal(1, 1) 
    end 

    describe "it can move to a floor" do 
    before do 
    end 

    it "should move to floor 2" do 
     e = Elevator.new 
     e.run 
     assert_equal(e.current_floor, 2) 
    end 
    end 
end 

Также, пожалуйста, не забудьте использовать .each при определении @@moves - она ​​возвращает перечислитель. Мы можем назвать .next только на счетчике

+0

Спасибо! Это объяснение помогает много, и тесты проходят сейчас :) – SoSimple