Я пытаюсь использовать RSpec для тестирования класса, который записывает в файл. Но я хочу, чтобы тесты были быстрыми, поэтому вместо использования реального файла и записи на диск я хочу использовать StringIO в тестах и записывать в память.
В очень упрощенном виде, скажем, у меня есть этот тест:
RSpec.describe Writer do
it 'replaces the contents of the file' do
file = StringIO.new('foo')
writer = described_class.new(file)
one_contact = [{ 'name' => 'name', 'address' => 'address' }]
writer.write(one_contact)
expect(file.string).to eq('[{"name":"name1","address":"address1"}]')
end
end
и скажем, класс писателя выглядит так:
require 'json'
class Writer
def initialize(file)
@file = file
end
def write(contacts)
file.truncate(0)
file.write(contacts.to_json)
file.flush
end
private
attr_reader :file
end
когда я запускаю тесты через Rspec, я получаю сообщение об ошибке:
Failure/Error: file.truncate(0)
IOError:
not opened for writing
Если я заменю truncate
на что-то другое, я получу эту ошибку в строке, которая вызывает write
на file
.
Однако, если я сделаю это в pry, это сработает:
$ pry
[1] pry(main)> require_relative 'lib/db/writer'
=> true
[2] pry(main)> file = StringIO.new('foo')
=> #<StringIO:0x0000563c99220f70>
[3] pry(main)> writer = Writer.new(file)
=> #<Writer:0x0000563c98ff8950 @file=#<StringIO:0x0000563c99220f70>>
[4] pry(main)> one_contact = [{ 'name' => 'name', 'address' => 'address' }]
=> [{"name"=>"name", "address"=>"address"}]
[5] pry(main)> writer.write(one_contact)
=> #<StringIO:0x0000563c99220f70>
[6] pry(main)> file.string
=> "[{\"name\":\"name\",\"address\":\"address\"}]"
Если я сделаю это в обычном файле ruby и запущу его с помощью ruby, например:
require_relative 'lib/db/writer'
file = StringIO.new('foo')
writer = Writer.new(file)
one_contact = [{ 'name' => 'name1', 'address' => 'address1' }]
writer.write(one_contact)
puts file.string
Это также работает.
Это очень простое приложение Ruby, без зависимостей или фреймворков, вот как выглядит Gemfile:
source 'https://rubygems.org'
ruby '2.5.1'
gem 'sqlite3'
group :test do
gem 'coveralls', require: false
gem 'pry'
gem 'rake'
gem 'rspec'
gem 'rubocop', require: false
end
Актуальные версии драгоценных камней:
- sqlite3 (1.3.13)
- комбинезон (0.8.22)
- подглядывать (0.11.3)
- грабли (12.3.1)
- рспек (3.7.0)
- рубокоп (0.58.1)
Как я могу открыть StringIO для записи? Я хочу продолжать писать в память, а не на диск при тестировании.
StringIO
? - person Sergio Tulentsev   schedule 24.07.2018bundle
иrspec
- person Xirux Nefer   schedule 24.07.2018