我有几个 RSpec 示例共享以下复杂的期望,其中数组records
和浮点数min_long
, max_long
, min_lat
,max_lat
在这些示例之间有所不同。
expect(records).to all have_attributes(
shape: have_attributes(
exterior_ring: have_attributes(
points: all(
have_attributes(
longitude: be_between(min_long, max_long),
latitude: be_between(min_lat, max_lat)
)
)
)
)
)
(期望检查各个测试产生的所有记录是否具有完全包含在特定于测试的边界框中的形状(在我的情况下为RGeo Polygon )。)
为了减少重复并通过在其上粘贴名称来使复杂期望的意图更清晰,我将其提取到一个方法中:
def expect_in_bbox(records, min_long, max_long, min_lat, max_lat)
expect(records).to all have_attributes(
shape: have_attributes(
exterior_ring: have_attributes(
points: all(
have_attributes(
longitude: be_between(min_long, max_long),
latitude: be_between(min_lat, max_lat)
)
)
)
)
)
end
这很好用,但现在我必须用例如调用该方法
expect_in_bbox(valid_records, 12.55744, 12.80270, 51.36250, 51.63187)
在我的例子中。
这在 RSpec 的规范 DSL 中看起来很陌生。我希望能够写作
expect(valid_records).to be_in_bbox(12.55744, 12.80270, 51.36250, 51.63187)
或者
expect(valid_records).to all be_in_bbox(12.55744, 12.80270, 51.36250, 51.63187)
反而。
有没有推荐的方法来实现这一目标?
我认为我不能为此使用 RSpec 的匹配器别名工具,因为它们似乎只将匹配器 名称映射到其他匹配器 名称,而不是完整的带有参数的匹配器调用。不过,也许 的options
论点alias_matcher
是为此而生的?
当然,我也可以实现一个自定义匹配器,但是我可能会被迫提供一个返回布尔值的实现,这与它由现有的匹配器组成相矛盾。(并不是说这很难,但我喜欢使用all
和之类的东西来实现be_between
。)
最后,我还可以对元素的类进行猴子补丁valid_records
以具有in_bbox?(min_long, max_long, min_lat, max_lat)
属性,以便 RSpec 自动提供相应的be_in_bbox(min_long, max_long, min_lat, max_lat)
匹配器。