我正在尝试使用RSpec来测试写入文件的类。但是我希望测试速度很快,所以我不想在测试中使用StringIO并写入内存,而不是使用真实的文件并写入磁盘。
以一种非常简化的方式,让我说我有这个测试:
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
假设writer类是这样的:
Failure/Error: file.truncate(0)
IOError:
not opened for writing
通过Rspec运行测试时,出现错误:
truncate
如果我将write
更改为其他内容,则会在调用file
上的$ 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\"}]"
的行中收到此错误。
但是,如果我撬开它,它会起作用:
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文件中执行该操作,然后使用ruby运行它,则:
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
它也可以正常工作。
这是一个超级简单的Ruby应用程序,没有依赖项或框架,这就是Gemfile的样子:
protected
宝石的实际版本:
如何打开StringIO进行编写?我想继续写入内存而不是测试中的磁盘。
答案 0 :(得分:2)
这是您的问题:
# frozen_string_literal: true
您的字符串contents
被冻结,无法修改。 StringIO用上述IOError
表示它。