我一直试图测试一个模拟电梯两天的程序,但收效甚微。这是我的电梯课程,该计划仍在进行中,我还评论了一些可能对我遇到问题的考试不重要的方法。如果您认为需要,我会很乐意展示更多代码
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
我试图测试电梯是否可以移动到特定楼层。起初,我无法在不运行程序本身的情况下测试控制台的输入。我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
未被正确覆盖并且运行测试套件提示用户输入,因此建议我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
并为current_floor
添加attr_accessor,因为我的方法缺少错误。
问题:此测试会出现以下错误:
1)失败:它可以移动到一个楼层#test_0001_should移动到楼层2 [elevator_test.rb:24]:预计:无实际:2
我试图尽可能地整理Elevator类,并保持方法尽可能简单,因为我可以给出程序的参数。
任何人都可以指出我正确的方向来解决这个问题,可能有伪代码示例(如果可能的话)来演示如果答案是重构我应该如何解决这个问题。
请记住,我还要执行其他测试,例如检查电梯类可以维护楼层列表,还是可以改变方向,将来当您回答时。
答案 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