我想在包含数组的元素类上断言,我尝试了以下方法:
这不起作用,但看起来很好看和可读:
["String", :symbol, Object.new].should =~ [an_instance_of(String), an_instance_of(Symbol), an_instance_of(Object)]
但是给了我以下错误:
Failure/Error: ["String", :symbol, Object.new].should =~ [an_instance_of(String), an_instance_of(Symbol), an_instance_of(Object)]
expected collection contained: [#<RSpec::Mocks::ArgumentMatchers::InstanceOf:0x007f9e6a33dbe0 @klass=String>, #<RSpec::Mocks::ArgumentMatchers::InstanceOf:0x007f9e6a33dbb8 @klass=Symbol>, #<RSpec::Mocks::ArgumentMatchers::InstanceOf:0x007f9e6a33db68 @klass=Object>]
actual collection contained: ["String", :symbol, #<Object:0x007f9e6a33dca8>]
the extra elements were: ["String", :symbol, #<Object:0x007f9e6a33dca8>]
请注意,没有遗漏的元素。
这很有效,但看起来很讨厌:
["String", :symbol, Object.new].collect{|x| x.class}.should =~ [String, Symbol,Object]
答案 0 :(得分:3)
您可以使用&:class
代替块
["String",:symbol,Object.new].map(&:class).should =~ [String,Symbol,Object]
产生相同但更具可读性。
另外,我使用map
这是collect
方法的简短别名。
答案 1 :(得分:2)
第二部分的答案取决于你的断言“请注意,没有遗漏的元素。” 缺少元素。
此:
expected collection contained: [#<RSpec::Mocks::ArgumentMatchers::InstanceOf:0x007f9e6a33dbe0 @klass=String>, #<RSpec::Mocks::ArgumentMatchers::InstanceOf:0x007f9e6a33dbb8 @klass=Symbol>, #<RSpec::Mocks::ArgumentMatchers::InstanceOf:0x007f9e6a33db68 @klass=Object>]
与此不同:
the extra elements were: ["String", :symbol, #<Object:0x007f9e6a33dca8>]
第一个包含类实例的模拟对象,第二个包含类的实例。 instance_of
匹配器不应该以这种方式使用,你会这样做吗?
["String", :symbol, Object.new].should =~ [respond_to(:gsub), respond_to(:intern), respond_to(:object_id)]
它没有意义,因为您应该测试数组 或数组的内容每个都具有某种属性。你所做的就是混淆两个测试,这样做会导致两者都出现问题。
subject { instance }
["String", :symbol, Object.new].each do |thing|
let(:instance) { thing.class }
if instance.class == String
it{ should respond_to(:gsub) }
else #...
更像这样的东西,但我认为这仍然是代码/设计气味 - 为什么你会在同一个数组中有这样不同的东西?规范,测试和处理都很困难。