使用MiniTest测试无限循环并使用模拟

时间:2015-05-06 01:22:51

标签: ruby tdd minitest

我的代码中有一个部分,用于轮询队列中的消息,然后根据消息类型对其进行操作:

@queue = Foo::Queue.new
loop do
  @queue.poll do |message|                                                                                                                              
    if message[:task] == TAKEACTION
      result = takeaction(message)
      @queue.send_result(result, message)
    end
    @queue.pong(message) if message[:task] == PING
  end
end

如何设置测试以提供单个message并验证@queue是否按预期对其进行操作?

我在minitest中看到很少测试块,并且在ruby中没有找到关于打破无限循环的任何东西,尽管我在python中找到了一个想法,你设置了第二次运行以抛出异常。

任何红宝石/最小的大师都能帮忙吗?

1 个答案:

答案 0 :(得分:0)

对于使用存根的minitest将起作用。下面的示例是自包含的,可以单独运行。您可以将一个异常作为带有存根的lambda发送,以打破无限循环并继续测试。

# class receiving the messages from class being tested
class Obj
  def method_if_true
    # do some stuff
    return 'anything that is true'
  end

  def method_if_false
    # do some stuff
    false
  end
end

# class to be tested
class TestingLoop
  def initialize(args)
    @obj = args.fetch(:object, Obj.new)
    @bool = args[:bool]
  end

  def looping
    loop do
      if @bool
        @obj.method_if_true
        # @bool is true
      elsif !@bool
        @obj.method_if_false
        # @bool is false
      end
    end
  end
end

require 'minitest/autorun'
# class that tests
class TestTestingLoop < MiniTest::Test
  def setup
    @obj = Obj.new
    @raises_exception = lambda { raise RuntimeError.new }
    # could use the '->' syntax instead of the word lambda
  end

  def test_sends_correct_method_when_true
    @obj.stub :method_if_true, @raises_exception do
      testing_loop = TestingLoop.new({object: @obj, bool: true})
      assert_raises(RuntimeError) { testing_loop.looping }
    end
  end

  def test_sends_correct_method_when_false
    @obj.stub :method_if_false, @raises_exception do
      testing_loop = TestingLoop.new({object: @obj, bool: false})
      assert_raises(RuntimeError) { testing_loop.looping }
    end
  end
end