minitest - 模拟 - 期望关键字参数

gra*_*olf 10 ruby mocking minitest

当我想验证模拟是否发送了预期的参数时,我可以这样做

@mock.expect(:fnc, nil, ["a, "b"])
Run Code Online (Sandbox Code Playgroud)

但是,如果我想模拟的课程看起来像这样

class Foo
    def fnc a:, b:
    end
end
Run Code Online (Sandbox Code Playgroud)

我如何模拟它并验证作为a:,传递的值b:

Jia*_*ang 10

下面是我公司代码库中的一个真实示例:

mailer = MiniTest::Mock.new
mailer.expect :deliver, 123 do |template_name:, data:, to:, subject:|
  true
end
mailer.deliver template_name: "xxx", data: {}, to: [], subject: "yyy"
Run Code Online (Sandbox Code Playgroud)

如果您还想验证参数的类型:

mailer.expect :deliver, 123 do |template_name:, data:, to:, subject:|
  template_name.is_a?(String) &&
    data.is_a?(Hash) &&
    to.is_a?(Array) &&
    subject.is_a?(String) &&
end
Run Code Online (Sandbox Code Playgroud)

更新2022-05-22

ArgumentError如果您将此策略与 Ruby v3 结合使用,您将会得到这样的结果。

我已经在这里提交了一个 PR 来解决这个问题:

https://github.com/minitest/minitest/pull/908

如果您希望在 Ruby v3 中使用此功能,请留下一些评论以引起项目所有者的注意。

更新2022-06-28

minitest 从 v5.16.0 开始支持关键字参数

https://github.com/minitest/minitest/blob/master/History.rdoc#5160--2022-06-14-

  • 我也很困惑,认为发生了一些元魔法,但想象一下该方法实际上被称为“deliver”而不是“send”,并且示例变得简单明了:您只是在嘲笑“deliver”方法,并传递一个块来验证期望,而不是让模拟对象使用其默认实现来验证它。 (2认同)