Home>
Event

I was testing the process of saving a hash export to a file, and when I tried to test it using StringIO,
I got the following error message.

1) Create Hoge file use StringIO
     Failure/Error: Hoge.test (def_path)
       #<File (class)>asked to yield | [#<String IO: 0x000055e05af5b758>] | but no block was passed


It seems that the block (file) is not passed, as you can see from the error message.
Stub FileIO with RSpec
↑ I intended to refer to the example here.

When testing YAML output, please tell us where to improve.

test results
Hoge
  File creation
    use StringIO (FAILED -1)
Failures:
  1) Create Hoge file use StringIO
     Failure/Error: Hoge.test (def_path)
       #<File (class)>asked to yield | [#<String IO: 0x0000559cfcbfe660>] | but no block was passed
     # ./lib_sc.rb: 7: in `test'
     # ./spec/lib_sc_spec.rb:13: in `block (3 levels) in<top (required)>'
Finished in 0.01155 seconds (files took 0.30146 seconds to load)
1 example, 1 failure
Failed examples:
rspec ./spec/lib_sc_spec.rb:10 #Create Hoge file use StringIO
Source

lib_sc.rb

require'yaml'
require'json'
class Hoge
  def self.test (conf_path)
    data = {"fruits" =>["Orange", "Apple", "Grape"]}
    YAML.dump (data, File.open (conf_path,'w'))
  end
end

spec/lib_sc_spec.rb

require'stringio'
require'tempfile'
require'fileutils'
require_relative'../lib_sc.rb'
RSpec.describe Hoge do
  let (: def_path) {File.join (__ dir __,'Assets/def_file.yml')}
  describe'Create file' do
    it'use StringIO' do
      file = StringIO.new ('','w')
      allow (File) .to receive (: open) .and_yield (file)
      Hoge.test (def_path)
    end
  end
end
environment
$uname -a
Linux ansible-web 4.15.0-54-generic # 58-Ubuntu SMP Mon Jun 24 10:55:24 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
$ruby ​​-v
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-linux]
$rspec -v
RSpec 3.9
  --rspec-core 3.9.2
  --rspec-expectations 3.9.2
  --rspec-mocks 3.9.1
  --rspec-support 3.9.3

that's all, thank you very much.

  • Answer # 1

    allow (File) .to receive (: open) .and_yield (file)

    and_return (file)I think.

    Or

    def self.test (conf_path)
        data = {"fruits" =>["Orange", "Apple", "Grape"]}
        File.open (conf_path,'w') {| file | YAML.dump (data, file)}
      end

  • Answer # 2

    File.open (conf_path,'w') {| f | YAML.dump (data)}

    Is the place wrong? Should I do the following?

    File.open (conf_path,'w') {| f | f<<YAML.dump (data)}

    Reference: https://docs.ruby-lang.org/ja/latest/class/Psych.html#S_DUMP