为产生的方法编写 Minitest 测试的正确方法是什么?

What is the proper way to write a Minitest test for a method that yields?

我在 class 中有一个方法定义如下:

  def show_benefits_section?
    yield if has_any_context?
  end

我想围绕这个写一个测试,到目前为止我有这个(有效):

  test_class.stub(:has_any_context?, true) do
    test_class.show_benefits_section? do |show_section=true|
      assert_equal(show_section, true)
    end
  end

我只是不确定这是否是测试该方法的最佳方式... 我该如何测试负面情况?

如有任何帮助,我们将不胜感激!

首先,您的代码没有测试任何内容,无论如何它总是成功。试试这个,它成功了,证明了这一点:

[1].each do |first=nil, second=2|
  assert_equal(1, first)
  assert_equal(2, second)
end

让我解释一下;无论如何,变量 second 始终为 2,因为方法 each 不会影响它并且默认设置为 2。相比之下,[= 的默认值 nil 16=] 被忽略,因为 each 传递了一个对象。

这是用于测试您的案例的改进代码片段。 它测试块 return 为真和假的情况,以及 has_any_context? 为真和假的情况。我不认为有一种通用的方法可以专门验证块的产生值。相反,您验证方法 returns.

# Test: :has_any_context? == true 
test_class.stub(:has_any_context?, true) do
  # Test: a block must be given.
  assert_raises(LocalJumpError) { test_class.show_benefits_section? }

  # Test: yield
  [true, false, 5].each do |tobe|
    # If 5 is given, 5 is returned.
    ret = test_class.show_benefits_section? do
      tobe
    end
    assert_equal(tobe, ret)
  end
end

# Test: :has_any_context? == false
test_class.stub(:has_any_context?, false) do
  ret = test_class.show_benefits_section?{true}
  assert_nil(ret)
end

请注意,您的方法 show_benefits_section? return 是块中 return 的任何内容。我上面的例子也通过给定一个随机值 5 来测试它。在 Ruby 的约定中,方法名称以 '?' 结尾。应该 return 为 true 或 false(尽管有像 FileTest.size? 这样的例外)。如果你想遵循惯例,最简单的方法可能是将相关部分重写为

!!yield if has_any_context?

完成此修改后,您现在可以确认上面的测试失败了。