2012-07-31 68 views
6

我正在尝试从一个对象中剔除Net :: SFTP。这里的模型: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 

这里的规格:

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 

这里的堆栈跟踪:

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: 

首先,是我的方法就在这里?我想删除SFTP的功能,因为我们可以确信它已经很好地测试过了。相反,我想专注于确保文件流由get_file_stream()中的“黑盒子”返回。

其次,我该如何正确地取出sftp.file.open()来完成此操作?

在此先感谢您的任何想法!

回答

7

首先嘲讽了SFTP是有两个原因一个好主意:

  1. 你不是写一个SFTP测试,重点测试只是你设置 了测试。
  2. 您可以在测试中删除对网络的任何依赖关系 - 您不希望由于某些事情无法控制而导致测试开始失败。

至于错误去,这是你的直接问题:

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

在这里,我们磕碰entry.name("filename")而不仅仅是entry.name

将其更改为:

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

,让我知道你上车。

+0

@cheesewasel - 工作就像一个魅力!谢谢您的帮助! – Sly 2012-07-31 17:16:55

+0

完全没问题。 :) – 2012-08-01 02:23:36