【问题标题】:RSpec: stubbing SFTP - private method calledRSpec:存根 SFTP - 称为私有方法
【发布时间】:2012-07-31 18:31:27
【问题描述】:

我正在尝试在模型中剔除 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).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

这是堆栈跟踪:

NoMethodError in 'SftpToServer should return a file stream'
private method `open' called for #<Object:0x10c572620>
/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:

我已经用谷歌搜索了这个,但我不明白为什么 RSpec 会将 sftp.file.open 视为私有方法...

提前感谢您的任何想法!

【问题讨论】:

    标签: ruby-on-rails rspec mocking sftp


    【解决方案1】:

    所以,我知道发生了什么——我没有将 open() 方法描述为 @sftp_mock 对象的一部分,所以 @sftp.file.open 看起来像一个私有方法。解决这个问题需要让@sftp_mock.file 返回@sftp_mock,这样它就可以像这样链接到 open() 方法:

    @sftp_mock.stub!(:file) { @sftp_mock }
    @sftp_mock.should_receive(:open).with("some/pathname/filename").and_return(@file)
    

    我也错过了@file 声明...完整的规范文件是:

    require 'spec_helper'
    
    describe "SftpToServer" do
      let(:ftp) { BatchTask::SftpToServer.new }
    
     it "should return a file stream" do
        @file = File.new("#{RAILS_ROOT}/spec/files/express_checkout_tdr.csv", "r")
        @sftp_mock = mock('sftp')
        @entry = File.stubs(:reads).with("filename").returns(@file)
        @entry_mock = mock('entry')
        @entry_mock.stub(:name).and_return("filename")
        @sftp_mock.stub_chain(:dir, :glob).and_yield(@entry_mock)
        Net::SFTP.stub(:start).and_yield(@sftp_mock)
        @sftp_mock.stub!(:file) { @sftp_mock }
        @sftp_mock.should_receive(:open).with("some/pathname/filename").and_return(@file)
    
        ftp.get_file_stream("ftp.test.com", "user", "password", "some/pathname", "filename").should be_kind_of(IO)
      end
    
    end
    

    另一个 stackoverflow 问题帮助我了解了这个概念:Stub chain together with should_receive

    此外,如果有更好的模拟和存根 SFTP 的方法,请随时发表评论。这个规范示例变得有点丑!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多