質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

RSpec

RSpecはRuby用のBDD(behaviour-driven development)フレームワークです。

ユニットテスト

ユニットテストは、システムのテスト手法の一つで、個々のモジュールを対象としたテストの事を指します。対象のモジュールが要求や性能を満たしているか確認する為に実行します。

Q&A

解決済

2回答

1614閲覧

Rspec StringIOを利用したYAML.dumpにてエラーが発生する

kurokoSin

総合スコア133

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

RSpec

RSpecはRuby用のBDD(behaviour-driven development)フレームワークです。

ユニットテスト

ユニットテストは、システムのテスト手法の一つで、個々のモジュールを対象としたテストの事を指します。対象のモジュールが要求や性能を満たしているか確認する為に実行します。

0グッド

0クリップ

投稿2020/09/13 14:53

事象

あるhashの書き出しをファイルに保存する処理のテストをしていて、StringIOを使ってテストしようとしたところ、
下記エラーメッセージがでました。

1) Hoge ファイルの作成 use StringIO Failure/Error: Hoge.test(def_path) #<File (class)> asked to yield |[#<StringIO:0x000055e05af5b758>]| but no block was passed

エラーメッセージから察するにブロック(file)が渡されていない様にみえますが、
RSpecでFileIOをスタブにする
↑ここのお手本を参考にできているつもりでありました。

YAMLの出力テストする場合、どこを改良したら良いかご教示お願いします。

テスト結果

Hoge ファイルの作成 use StringIO (FAILED - 1) Failures: 1) Hoge ファイルの作成 use StringIO Failure/Error: Hoge.test(def_path) #<File (class)> asked to yield |[#<StringIO: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 # Hoge ファイルの作成 use StringIO

ソース

lib_sc.rb

ruby

1require 'yaml' 2require 'json' 3 4class Hoge 5 def self.test(conf_path) 6 data = { "fruits" => ["Orange", "Apple", "Grape"] } 7 YAML.dump( data, File.open(conf_path, 'w') ) 8 end 9end

spec/lib_sc_spec.rb

ruby

1require 'stringio' 2require 'tempfile' 3require 'fileutils' 4require_relative '../lib_sc.rb' 5 6RSpec.describe Hoge do 7 let(:def_path){ File.join(__dir__, 'Assets/def_file.yml') } 8 9 describe 'ファイルの作成' do 10 it 'use StringIO' do 11 file = StringIO.new('','w') 12 allow(File).to receive(:open).and_yield(file) 13 Hoge.test(def_path) 14 end 15 end 16end

環境

$ 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

以上、よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ruby

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

のところが間違っているかと。以下のようにすべきなのでは?

ruby

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

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

投稿2020/09/14 03:27

taichi730

総合スコア318

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kurokoSin

2020/09/14 13:14

補足いただいてありがとうございました。 こちらのコードでも動作することが確認できました!
guest

0

ベストアンサー

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

and_return(file)かと思います。

もしくは

ruby

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

投稿2020/09/13 15:02

asm

総合スコア15147

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kurokoSin

2020/09/13 15:44

素早い回答大変ありがとうございます。 両方ためしてみたところ、前者は想定通りの動きをしてくれました。 ですが、後者のソースを修正する方は例外は発生しなくなったのですが、 テストで中身を書き出すと、""(文字列)になってしまいました。 実際にファイルを書き出しても中身が出力されなくなってしまいました。 後者のソースは何がいけないのでしょうか。 テストコード(spec/lib_sc_spec.rb 抜粋) ----- describe 'ファイルの作成' do it 'dont use StringIO' do Hoge.test(def_path) end it 'use StringIO' do file = StringIO.new('','w') allow(File).to receive(:open).and_yield(file) # allow(File).to receive(:open).and_return(file) Hoge.test(def_path) p file.string end end テストコード(lib_sc.rb 抜粋) ----- def self.test(conf_path) data = { "fruits" => ["Orange", "Apple", "Grape"] } # YAML.dump( data, File.open(conf_path, 'w') ) File.open(conf_path, 'w'){|f| YAML.dump( data ) } end
kurokoSin

2020/09/13 15:48

一応望む結果は得られたので、クローズにすべきか迷いましたが、こちらで質問させていただきました。 別途質問を立てるべきであればお申しつけください。
asm

2020/09/14 05:39

> File.open(conf_path, 'w'){|f| YAML.dump( data ) } File.open(conf_path, 'w'){|f| YAML.dump( data, f ) } です。
kurokoSin

2020/09/14 13:13

ありがとうございました。 無事 全て望んだ結果になりました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問