我为 RR 创建了一个通配符匹配器,通过将 JSON 字符串解析为哈希来匹配它们。这是因为 JSON(反)序列化不保留顺序;如果我们有:
{ 'foo': 42, 'bar': 123 }
。然后在(反)序列化之后,我们可能会发现我们的 Update 方法被调用:
{ 'bar': 123, 'foo': 42 }
通配符匹配器如下所示:
class RR::WildcardMatchers::MatchesJsonString
attr_reader :expected_json_hash
def initialize(expected_json_string)
@expected_json_hash = JSON.parse(expected_json_string)
end
def ==(other)
other.respond_to?(:expected_json_hash) && other.expected_json_hash == self.expected_json_hash
end
def wildcard_matches?(actual_json_string)
actual_json_hash = JSON.parse(actual_json_string)
@expected_json_hash == actual_json_hash
end
end
module RR::Adapters::RRMethods
def matches_json(expected_json_string)
RR::WildcardMatchers::MatchesJsonString.new(expected_json_string)
end
end
。我们像这样使用它:
describe 'saving manifests' do
before do
@manifests = [
{ :sections => [], 'title' => 'manifest1' },
{ :sections => [], 'title' => 'manifest2' }
]
mock(manifest).create_or_update!(matches_json(@manifests[0].to_json)) { raise 'uh oh' }
mock(manifest).create_or_update!(matches_json(@manifests[1].to_json))
parser = ContentPack::ContentPackParser.new({
'manifests' => @manifests
})
@errors = parser.save
end
it 'updates manifests' do
manifest.should have_received.create_or_update!(anything).twice
end
end
这符合 RR 文档。 但是,mock()
期望参数与 JSON 匹配,而是期望参数是MatchesJsonString
对象:
1) ContentPack::ContentPackParser saving manifests updates manifests
Failure/Error: mock(Manifest).create_or_update!(matches_json(@manifests[0].to_json)) { raise 'uh oh' }
RR::Errors::TimesCalledError:
create_or_update!(#<RR::WildcardMatchers::MatchesJsonString:0x13540def0 @expected_json_hash={"title"=>"manifest1", "sections"=>[]}>)
Called 0 times.
Expected 1 times.
# ./spec/models/content_pack/content_pack_parser_spec.rb:196
答案是我链接到的文档中有拼写错误。 这(我的强调):
#wildcard_matches?(other)
wildcard_matches? is the method that actually checks the argument against the expectation. It should return true if other is considered to match, false otherwise. In the case of DivisibleBy, wildcard_matches? reads:
。实际上应该读作:
#wildcard_match?(other)
...
我的一位同事建议我们将我们的代码与 rr gem 中定义的匹配器之一进行比较,然后差异就很明显了。