我为RR创建了一个通配符匹配器,它通过将JSON字符串解析为哈希值来匹配它们。这是因为JSON(de)序列化不保留顺序;如果我们有:
{ 'foo': 42, 'bar': 123 }
...然后在(de)序列化之后,我们可能会发现我们的更新方法被调用:
{ '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 documentation。但是,不是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
答案 0 :(得分:0)
答案是我链接的文档中存在拼写错误。这(我的重点):
#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中定义的匹配器之一进行比较,然后差异突出。