【问题标题】:How can I unit test a method that takes stdin within a loop?如何对在循环中采用标准输入的方法进行单元测试?
【发布时间】:2016-11-17 11:49:55
【问题描述】:

我在class QuestionList中有如下方法

def ask_all
    @questions.each do |question|
        question.ask
        @player.add_answer(gets.chomp)
    end
end

这些问题有整数答案,并且答案对于这个测试不必是正确的 - 只需要接收一个整数并将其添加到列表@player.answers 中,使用class Player 中的以下方法

def add_answer(answer)
    @answers << answer
end

当对方法进行单元测试时,如何模拟用户对QuestionList.ask_allgets.chomp 的输入:

class QuestionListTest < Test::Unit::TestCase

    def setup
        ...
    end

    def test_ask_all
        #unit test for 'QuestionList.ask_all' here
    end

end

【问题讨论】:

  • @player.add_answer((1..10).to_a.sample)
  • 我如何在 &lt; Test::Unit::TestCase 类中实现它?
  • 显然用return (1..10).to_a.sample模拟@player#add_answer
  • 我仍然不知道如何在我的 test_ask_all 方法中实现它? @player.add_answer 将答案添加到列表并返回列表。所以,在我的测试方法中,我需要类似于assert_equal([1], @questions.ask_all) 的东西,但是ask_all 里面有@player.add_answer(gets.chomp) 行,所以gets.chomp 不可能在测试类中执行,我不知道如何执行您的建议 - 只有在测试类中运行时,ask_all 才会使用行 @player.add_answer((1..10).to_a.sample) 执行,但在主程序中运行时不会执行。
  • @mudasobwa 我在我的 OP 中添加了更多信息

标签: ruby unit-testing user-input stdin


【解决方案1】:

1。将ask_all 修改为与输入无关:

def ask_all
    @questions.each do |question|
        question.ask
        @player.add_answer(question.retrieve_answer)
    end
end

2。修改Question类,使其拥有retrieve_answer方法:

class Question
  def ask
    # even better, delegate this to some other class
    #  to make it possible to work with console,
    #  batches, whatever depending on settings
    print "Enter an answer >"
  end
  def retrieve_answer
    # for now it’s enough
    gets.chomp
  end
end

3。模拟Question 类以非交互方式“提问”:

class QuestionListTest < Test::Unit::TestCase

    def setup
      Question.define_method :ask do
        print "I am mock for prompting ... "
      end
      Question.define_method :retrieve_answer do
        # be aware of wrong input as well!
        [*(1..10), 'wrong input', ''].sample.tap do |answer|
          puts "mocked answer is #{answer}." 
        end
      end
    end

    def test_ask_all
      expect(ask_all).to match_array(...)
    end
end

【讨论】:

    猜你喜欢
    • 2011-08-22
    • 1970-01-01
    • 2019-05-05
    • 2015-01-25
    • 2014-08-05
    • 1970-01-01
    • 2013-11-26
    • 1970-01-01
    • 2019-05-10
    相关资源
    最近更新 更多