我为RR创建了一个通配符匹配器,它通过将 JSON 字符串解析为哈希来匹配它们。这是因为 JSON(反)序列化不保留顺序;如果我们有:
{ 'foo': 42, 'bar': 123 }
...然后在(反)序列化之后,我们可能会发现我们的更新方法被调用:
{ '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