RSpecinstance_doublerespond_to?奇怪的行为

RSpec instance_double respond_to? strange behavior

我有

let(:ssl_socket) { instance_double(OpenSSL::SSL::SSLSocket) }

现在我想测试我拥有的对象是否是 OpenSSL::SSL::SSLSocket 的实例。我不想使用 be_an_instance_of 匹配器,因为我希望我的测试更像 "duck typing" 方式。所以我想知道对象是否响应 'ssl_version' 方法

it 'should change socket to ssl' do
    #do some stuff and set socket = ssl_socket
    expect(socket).to respond_to(:ssl_version)
end

没用

expected #<InstanceDouble(OpenSSL::SSL::SSLSocket) (anonymous)> to respond to :ssl_version

但是如果我使用其他匹配器

it 'should change socket to ssl' do
    #do some stuff and set socket = ssl_socket
    expect(socket).to receive(:ssl_version)
    socket.ssl_version
end

然后 InstanceDouble 将实际检查 :ssl_version 方法是否存在于 OpenSSL::SSL::SSLSocket 个实例中。这是 RespondTo 匹配器的特性还是错误?我应该使用接收匹配器吗?

instance_double 基本上 creates a Struct instance 在幕后。

开箱即用,它是一个对象,对包装一无所知class。 receive 扩展了它的 stubs 属性。

所以是的,在这种情况下应该使用 receive。更准确地说,不应该测试 RSpec 本身,而你正在做的是测试 instance_double 实现。