2012-07-31 17 views
6

Estoy intentando colgar Net :: SFTP de un objeto. Aquí está el modelo:RSpec: Stubbing SFTP

class BatchTask 
    require 'net/sftp' 

    def get_file_stream(host, username, password, path_to_dir, filename) 
    raise ArgumentError if host.nil? or username.nil? or password.nil? or path_to_dir.nil? or filename.nil? 
    file_stream = nil 
    Net::SFTP.start(host, username, password) do |sftp| 
     sftp.dir.glob(path_to_dir, filename) do |entry| 
     # Verify the directory contents 
     raise RuntimeError(true), "file: #{path_to_dir}/#{filename} not found on SFTP server" if entry.nil? 
     file_stream = sftp.file.open("#{path_to_dir}/#{entry.name}") 
     end 
    end 
    file_stream 
    end 

end 

Aquí está la especificación:

require 'spec_helper' 

describe "SftpToServer" do 
    let(:ftp) { BatchTask::SftpToServer.new } 

it "should return a file stream" do 
    @sftp_mock = mock('sftp') 
    @entry = File.stubs(:reads).with("filename").returns(@file) 
    @entry_mock = mock('entry') 
    @entry_mock.stub(:name).with("filename").and_return("filename") 
    @sftp_mock.stub_chain(:dir, :glob).and_yield(@entry_mock) 
    Net::SFTP.stub(:start).and_yield(@sftp_mock) 
    @sftp_mock.stub_chain(:file, :open).with("filename").and_yield(@file) 

    ftp.get_file_stream("ftp.test.com", "user", "password", "some/pathname", "filename").should be_kind_of(IO) 
    end 

end 

Aquí está la StackTrace:

Spec::Mocks::MockExpectationError in 'SftpToServer should return a file stream' 
Mock "entry" received :name with unexpected arguments 
    expected: ("filename") 
     got: (no args) 
/Users/app/models/batch_task/sftp_to_server.rb:12:in `get_file_stream' 
/Users/app/models/batch_task/sftp_to_server.rb:9:in `get_file_stream' 
/Users/app/models/batch_task/sftp_to_server.rb:8:in `get_file_stream' 
./spec/models/batch_task/sftp_to_server_spec.rb:15: 

En primer lugar, es mi enfoque aquí? Quiero eliminar la funcionalidad de SFTP ya que podemos estar seguros de que está bastante probado. En su lugar, quiero centrarme en garantizar que la "caja negra" dentro de get_file_stream() devuelva una secuencia de archivos.

En segundo lugar, ¿cómo puedo anunciar correctamente sftp.file.open() para lograr esto?

¡Gracias de antemano por cualquier idea aquí!

Respuesta

7

En primer lugar bocetos fuera SFTP es una buena idea por dos razones:

  1. Usted no está escribiendo una prueba de SFTP, se centran en las pruebas simplemente lo que se propuso a prueba.
  2. Elimina cualquier dependencia de la red en sus pruebas; no desea que las pruebas comiencen a fallar debido a algo fuera de su control.

Por lo que va el error, este es su problema inmediato:

@entry_mock.stub(:name).with("filename").and_return("filename") 

Aquí está apagando entry.name("filename") en lugar de sólo entry.name.

Cambiar a:

@entry_mock.stub(:name).and_return("filename") 

y quiero saber cómo le va.

+0

@cheesewasel - funcionó como un encanto! ¡Gracias por la ayuda! – Sly

+0

Ningún problema en absoluto. :) –