是否有打开StringIO进行写入的事情?

时间:2018-07-24 15:06:22

标签: ruby rspec stringio

我正在尝试使用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

宝石的实际版本:

  • sqlite3(1.3.13)
  • 工作服(0.8.22)
  • 撬(0.11.3)
  • 耙(12.3.1)
  • rspec(3.7.0)
  • rubocop(0.58.1)

如何打开StringIO进行编写?我想继续写入内存而不是测试中的磁盘。

1 个答案:

答案 0 :(得分:2)

这是您的问题:

# frozen_string_literal: true

您的字符串contents被冻结,无法修改。 StringIO用上述IOError表示它。