0

I keep getting this validation error in rspec. Could someone please tell what I'm doing wrong?

  1) MyServer uses module
 Failure/Error: expect(MyClient.methods.include?(:connect)).to be true

   expected true
        got false
 # ./spec/myclient_spec.rb:13:in `block (2 levels) in <top (required)>'

This is my client.rb

#!/bin/ruby
require 'socket'

# Simple reuseable socket client

module SocketClient

  def connect(host, port)
    sock = TCPSocket.new(host, port)
    begin
      result = yield sock
    ensure
      sock.close
    end
    result
  rescue Errno::ECONNREFUSED
  end
end

# Should be able to connect to MyServer
class MyClient
  include SocketClient
end

And this is my spec.rb

describe 'My server' do

  subject { MyClient.new('localhost', port) }
  let(:port) { 1096 }

  it 'uses module' do
    expect(MyClient.const_defined?(:SocketClient)).to be true
    expect(MyClient.methods.include?(:connect)).to be true
  end

I have method connect defined in module SocketClient. I don't understand why the test keeps failing.

aprilduck
  • 15
  • 2

1 Answers1

0

The class MyClient doesn't have a method named connect. Try it: MyClient.connect will not work.

If you want to check what methods a class defines for its instances, use instance_methods: MyClient.instance_methods.include?(:connect) will be true. methods lists the methods an object itself responds to, so MyClient.new(*args).methods.include?(:connect) would be true.

Really, though, for checking whether a specific instance method exists on a class you should use method_defined?, and for checking whether an object itself responds to a specific method, you should use respond_to?:

MyClient.method_defined?(:connect)
MyClient.new(*args).respond_to?(:connect)

If you really do want MyClient.connect to work directly, you'd need to use Object#extend rather than Module#include (see What is the difference between include and extend in Ruby?).

Community
  • 1
  • 1
philomory
  • 1,709
  • 12
  • 13