无法正确获取 运行 的测试

Trouble getting tests to run properly

我已经尝试测试一个模拟电梯的程序两天了,但收效甚微。这是我的电梯 class,该程序仍在进行中,我还注释掉了一些对我遇到问题的测试可能不是必需的方法。如果您认为需要,我很乐意展示更多代码

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

我正在尝试测试电梯是否可以移动到特定楼层。起初,在没有 运行 程序本身的情况下,我无法从控制台测试输入。我 and was referred to 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 没有被正确覆盖并且 运行 测试服提示用户输入所以建议我 以确保该方法被正确覆盖。尝试这样做最终导致了这样的测试:

  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) Failure: it can move to a floor#test_0001_should move to floor 2 [elevator_test.rb:24]: Expected: nil Actual: 2

我已尝试尽可能地整理电梯 class 并使方法尽可能简单,因为我可以给定程序的参数。

任何人都可以指出我解决这个问题的正确方向,也许可以用伪代码示例(如果可能的话)来演示如果答案是重构,我应该如何解决这个问题。

请记住,我还想执行其他测试,例如检查电梯 class 是否可以维护楼层列表,或者它是否可以在将来回答时改变方向。

您的测试 class ElevatorTest 正在重新定义 Elevator 以覆盖方法 get_input,但它没有打开 class Elevatorelevator.rb 中定义,而是创建一个新的 class Elevator,恰好在 class ElevatorTest 中定义。记住每个 class 也是一个模块,所以现在你有一个新的 class 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

此外,请记住在定义 @@moves 时使用 .each - 它 returns 是一个枚举器。我们只能在枚举数

上调用 .next