有没有一种方法可以设置对哈希值的期望,但对键是符号还是字符串“不关心”?

问题描述 投票:0回答:1

使用 rspec-expectations 3.13.3 并具有如下代码:

def methname(**kwargs)
  # let's assume this method doesn't mind whether the kwargs are keyed by symbols or strings
  p(received: kwargs)
end

进行如下测试:

expect(something).to receive(:methname).with(hash_including(what_ever: "else"))

但在某些情况下,关键字参数被创建为字符串,而不是符号,因此失败,我必须这样做

expect(something).to receive(:methname).with(hash_including("what_ever" => "else"))

我可以在每个规范中做到这一点,但如果我能无差别地匹配它,对我来说会更干净 -

# desired code
expect(something).to receive(:methname).with(hash_including_indifferently(what_ever: "else"))

有办法做到这一点吗?

ruby rspec
1个回答
0
投票

要明确的是,方法签名

def methname(**kwargs)
不能接受
Hash
{"what_ever => "else"}
,但我认为你的意思是:

def methname(h = {})
  p(received: h)
end

如果您想以允许

h
包含
{"what_ever" => "else"}
{what_ever: "else"}
的方式进行测试,您可以按如下方式进行测试:

expect(something).to receive(:methname) do |h| 
  expect(h).to  include(what_ever: "else").or include("what_ever" => "else")
end

因为带有块的

receive
会产生块的参数,并且您可以在使用 Compound Expectation 时显式测试它们。

话虽如此,鉴于访问的目的是“无关紧要”,您可能需要测试为:

RSpec::Matchers.define_negated_matcher :not_include, :include

 expect(something).to receive(:methname) do |h| 
      expect(h).to  include("what_ever").and(
                      not_include(:what_ever)
                    ).or(
                      include(:what_ever).and(
                         not_include("what_ever")
                      )
                    ).and( 
                       include({"what_ever" => "else"}).or(
                        include({what_ever: "else"})
                       )
                   )
    end

这将防止

Hash
同时包含
"what_ever"
:what_ever
键,同时确保其中一个键存在且值为
"else"

© www.soinside.com 2019 - 2024. All rights reserved.