我有一个哈希数组,我试图Assert这个数组有确切的一定数量的哈希,按照一定的顺序,有特定的键。
假设我有一个水果数组。
fruits = [
{ name: 'apple', count: 3 },
{ name: 'orange', count: 14 },
{ name: 'strawberry', count: 7 },
]
当我将eq
匹配器与hash_including
(或其别名include
)一起使用时,Assert失败。
# fails :(
expect(fruits).to eq([
hash_including(name: 'apple'),
hash_including(name: 'orange'),
hash_including(name: 'strawberry'),
])
很奇怪,这不起作用,我总是找到一种方法绕过它,继续前进,但它已经困扰了我一段时间,所以我决定这次发布它。
我不想找的是
显然这是可行的,但我喜欢其他语法,因为这是这些匹配器的重点:所以我不需要手工转换我的数据结构,并且有更多可读的规范。
fruit_names = fruits.map { |h| h.fetch(:name) }
expect(fruit_names).to eq(['apple', 'orange', 'strawberry'])
contain_exactly
和include
可以工作,但我关心数组的确切大小和元素的顺序,它们无法Assert。
# passes but doesn't assert the size of the array or the order of elements
expect(fruits).include(
hash_including(name: 'apple'),
hash_including(name: 'orange'),
hash_including(name: 'strawberry'),
)
# passes but doesn't assert the exact order of elements
expect(fruits).contain_exactly(
hash_including(name: 'apple'),
hash_including(name: 'orange'),
hash_including(name: 'strawberry'),
)
3条答案
按热度按时间5lwkijsr1#
看起来你只需要使用
match
如果某个数组元素丢失或多余,此测试将失败
如果某些哈希不包括指定的键值对,则此测试将失败
如果数组元素顺序错误,则此测试将失败
vi4fp9gy2#
我不记得有任何内置的匹配器可以同时检查包含和顺序(UPD)。I'm wrong),同时在匹配值方面很灵活,但是如果你经常需要这些检查,你可以很容易地创建一个简单的自定义匹配器。
最基本的版本非常简单:
然后
但是有一个严重的缺点-如果顺序错误,这个匹配器不能提供足够的信息来轻松修复错误(它没有说 * 哪些元素 * 是不匹配的-对于2-3个元素来说不是什么大问题,但对于更大的集合,这可能是一个痛苦)。因此,理想情况下,我们需要调整失败信息,使其真正有帮助。类似于以下内容:
如果我们打乱了顺序:
我们的错误消息非常有用:
ruoxqz4g3#
你做的有点反模式。您几乎不应该编写具有这种复杂程度的测试,或者将多个测试捆绑到一个期望中。这样做会使结果的粒度变小,并使测试更难识别问题。
你最好对每个结果有不同的规范,或者只是寻找预期的数据或结构不变的完整数据结构。举例来说:
否则,如果你想要整个结构,只要确保它是有序的。数组是有序的,并且需要被排序为相等。哈希值保证插入顺序,但如果它们包含相同的内容,则无论顺序如何都是相等的,因此您需要比较:
当然,还有其他方法可以做到这一点,但关键是您希望您的测试是DAMP,而不是DRY,并使您的测试尽可能不受新逻辑的影响。否则,很可能会给测试带来复杂性,因为它会使用未经测试的测试逻辑,而不是简单地测试被测对象。YMMV.