如何使用Ruby minitest框架调用某些方法?

时间:2012-06-03 10:06:58

标签: ruby unit-testing testing minitest

我想测试函数是否使用minitest Ruby正确调用其他函数,但我找不到合适的assert来测试doc

源代码
class SomeClass
  def invoke_function(name)
    name == "right" ? right () : wrong ()
  end

  def right
    #...
  end

  def wrong
    #...
  end
end
测试代码:
describe SomeClass do
  it "should invoke right function" do
    # assert right() is called
  end

  it "should invoke other function" do
    # assert wrong() is called
  end
end

3 个答案:

答案 0 :(得分:23)

使用minitest,您可以使用expect方法设置在模拟对象上调用方法的期望,如此

obj = MiniTest::Mock.new
obj.expect :right

如果您想使用参数设置期望值并返回值,那么:

obj.expect :right, return_value, parameters

对于像这样的具体对象:

obj = SomeClass.new
assert_send([obj, :right, *parameters])

答案 1 :(得分:14)

Minitest有一个特殊的.expect :call用于检查是否调用了某个方法。

describe SomeClass do
  it "should invoke right function" do
    mocked_method = MiniTest::Mock.new
    mocked_method.expect :call, return_value, []
    some_instance = SomeClass.new
    some_instance.stub :right, mocked_method do
      some_instance.invoke_function("right")
    end
    mocked_method.verify
  end
end

不幸的是,这个功能没有很好地记录。我从这里找到了它:https://github.com/seattlerb/minitest/issues/216

答案 2 :(得分:3)

根据给定的示例,没有其他委托类,并且您希望确保从同一个类中正确调用该方法。然后下面的代码片段应该工作:

class SomeTest < Minitest::Test
  def setup
    @obj = SomeClass.new
  end

  def test_right_method_is_called
    @obj.stub :right, true do
      @obj.stub :wrong, false do
        assert(@obj.invoke_function('right'))
      end
    end
  end

  def test_wrong_method_is_called
    @obj.stub :right, false do
      @obj.stub :wrong, true do
        assert(@obj.invoke_function('other'))
      end
    end
  end
end

我们的想法是通过返回一个简单的 true 值来存根 [method_expect_to_be_called] ,并且在存根块中声明它确实被调用并返回<强大>真实价值。要存根,其他意想不到的方法就是确保它没有被调用。

注意:assert_send无法正常工作。请参阅official doc

事实上,以下声明将通过,但并不意味着它按预期工作:

assert_send([obj, :invoke_function, 'right'])
# it's just calling invoke_function method, but not verifying any method is being called