在Rspec中{Stub File.open

时间:2018-03-15 18:48:29

标签: ruby rspec mocking stub rspec3

我知道Stack Overflow中涵盖了这个主题,但是他们提供的任何解决方案对我都没有用。 2天被困在同一个......开始有点绝望了。

我的原始代码:

url = 'https://someurl/picture.jpg'
file = File.open('new_picture.jpg', 'wb') do |fo|
  fo <<  open(url).read
end

我无法弄清楚如何将此打开。 我尝试了什么(在一百个小替代品中都失败了)

let(:buffer) {StringIO.new}
let(:picture) {'picture.jpg'}
let(:content) { 'this is just a content to mock up the file' }

before do
  # previous stuff..
  allow(File).to receive(:open).with(picture, 'wb').and_yield(buffer)
end

it 'downloads the image' do
  expect(File).to receive(:open).with(picture,'wb')
  call # this is the way to call the method that contains File.open
end

所有时间都收到错误:

expected: ("picture.jpg", "wb")
got: ("/var/folders/55/1mv73gd50779nsdwwh6vkp280000gn/T/open-uri20180315-23631-9dokgj", 2562, {:perm=>384})

我缺少什么? 我也在块File.open(picture) { |f| f.write(content) }内尝试过。如果我不调用call,它就有效。所以我有一个绿色测试,它永远不会进入我想要测试的真实方法。

我的主要目标:从调用此调用的类中存储File.open。然后我只是希望随时都能接受开放...只是我想要那个!

更新 - 整体测试

require 'pry'
require 'spec_helper'

describe Downloader do
  let(:call) { Downloader.call }
  let(:path) { '/Users/testUser/Downloads/picture.jpg' }

  it 'returns a path' do
    expect(call).to be_a_kind_of(String)
  end

  xcontext 'when the image exists' do
    before { allow_any_instance_of(File).to receive(:exist?).and_return(true) }

    it 'returns the correct path' do
      allow(subject).to receive(:get_existing_file).and_return(path)
      expect(call).to match(/picture/)
      expect(call).to match(/Downloads/)
      expect(call).to match(/Users/)
    end
    it 'does not modify the system' do
      expect(File).not_to receive(:open)
    end
  end
  context 'when the image does not exists' do
    let(:buffer) { StringIO.new }
    let(:picture) { 'picture.jpg' }
    let(:content) { 'this is just a content to mock up the file' }

    before do
      allow(File).to receive(:exist?).and_return(false)
      allow(File).to receive(:open).with(picture, 'wb').and_yield(buffer)
    end

    it 'downloads the image' do
      >>>> GOT STUCK HERE, just removed what I had 
      call

    end
  end
end

最后我决定使用FakeFs模拟FileSystem。这是我的规范,检查它是否存在文件或是否存在。

require 'fakefs/spec_helpers'
require 'spec_helper'

describe Downloader do
  include FakeFS::SpecHelpers
  let(:call) { Downloader.call }
  let(:path) { '/Users/testUser/Downloads/example_picture.jpg' }
  let(:buffer) { instance_double(File, path: 'picture.jpg') }

  before do
    config = File.expand_path('~/Downloads', __FILE__)
    FakeFS::FileSystem.clone(config)
    allow(File).to receive(:open).and_return(buffer)
  end
  it 'returns a path' do
    expect(call).to be_a_kind_of(String)
  end

  context 'when the image exists' do
    before { allow_any_instance_of(File).to receive(:exist?).and_return(true) }

    it 'returns the correct path' do
      allow(subject).to receive(:get_existing_file).and_return(path)
      expect(call).to match(/example_picture/)
      expect(call).to match(/Downloads/)
      expect(call).to match(/Users/)
    end
    it 'does not modify the system' do
      expect(File).not_to receive(:open)
    end
  end
  context 'when the image does not exists' do
    before { allow(File).to receive(:exist?).and_return(false) }
    it 'downloads the image' do
      expect(File).to receive(:open)
      call
    end
    it 'puts in the right folder' do
      expect(Dir.pwd).not_to match(/Downloads/)
      call
      expect(Dir.pwd).to match(/Downloads/)
    end
    it 'returns the path with the new image' do
      result = call
      expect(result).to match(/Downloads/)
      expect(result).to match(/picture/)
    end
  end
end

0 个答案:

没有答案