我知道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 . 然后我只是希望随时都能获得开放......只是我想要那个!
UPDATED - whole test
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
SOLUTION
最后,我决定使用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