0

I'm mocking part of the Net::SFTP for my tests. The following mimicks dir.entries, entry.name and entry.attributes.size by reading locally from fixture_path:

class MockedSFTP
  mattr_accessor :fixture_path
  def dir
    Class.new do
      def entries(path)
        MockedSFTP.fixture_path.join(path.sub(%r{^/}, '')).children.map do |child|
          OpenStruct.new(
            name: child.basename,
            attributes: OpenStruct.new(size: child.size)
          )
        end
      end
    end.new
  end
end

An alternative would be:

class MockedSFTP
  mattr_accessor :fixture_path
  def dir
    object = Object.new
    def object.entries(path)
      MockedSFTP.fixture_path.join(path.sub(%r{^/}, '')).children.map do |child|
        OpenStruct.new(
          name: child.basename,
          attributes: OpenStruct.new(size: child.size)
        )
      end
    end
    object
  end
end

Both versions work absolutely fine, however, I don't like neither of them. The Class.new do ... end.new is just ugly and I'm no fan of object = Object.new; ...; object code at all.

Is there a third way to write this?

svoop
  • 3,318
  • 1
  • 23
  • 41

1 Answers1

0

How about actually declaring the class?

class MockedSFTP

  mattr_accessor :fixture_path

  class Dir
    def entries(path)
      MockedSFTP.fixture_path.join(path.sub(%r{^/}, '')).children.map do |child|
        OpenStruct.new(
          name: child.basename,
          attributes: OpenStruct.new(size: child.size)
        )
      end
    end
  end

  def dir
    Dir.new
  end
end
BroiSatse
  • 44,031
  • 8
  • 61
  • 86
  • That was my first shot, but it's even more verbose. I was looking for a more "anonymous" approach. – svoop Feb 03 '14 at 23:39