takumiblog

新人エンジニアの技術ブログ

nilはemptyにはならない??テストが失敗する原因について考察してみた。

はじめに

初めまして、takumiです!

今回はRSpecのテストが思った通りの動作がしなかったのでその原因について考察していこうと思います。

nilに関してちゃんと理解できる方であれば超絶簡単な内容かと思います。少しお付き合い頂ければ幸いです。

内容

noteというmodelが存在し。今回実装したいテストは「noteを新規作成する時にメッセージ(内容)が空の場合失敗することを期待」するような内容になっています。

※多分RSpecとかの問題の前にメソッドについてちゃんと理解できていないから今回の失敗が理解できなかったんだと自覚しています。ですが、例(RSpec)を使いながらの方が理解しやすいと思うので今回はRSpecで説明しながら解説していこうと思います。

予想して書いたテスト(失敗テスト)

RSpec.describe Note, type: :model do
  describe "noteを作成" do
    context "messageが空の時" do
      before do
        @note =Note.new(message: nil)
      end
      it "無効であること" do
        expect(@note).to be_empty
      end
    end
  end
end

問題の記述はここ。

 expect(@note).to be_empty 

@noteはnil(空)になっているため、emptyで「無効であること」が検証できるかと思っていました。

実行してみると。

[terminal]
Failure/Error: expect(@note).to be_empty
        expected #<Note id: nil, message: nil, project_id: nil, user_id: nil, created_at: nil, updated_at: nil, attach...file_name: nil, attachment_content_type: nil, attachment_file_size: nil, attachment_updated_at: nil> to respond to `empty?`

このようなエラーが発生しました。

empty→空。nil→ない。nil == empty ではない??

・現時点でわかることはnilはemptyではないということ、「空」と「ない」は別物ということ。

このエラーの原因を理解するには、nilとemptyについて理解する必要がある。

nil 

nilの場合のみtrueを返し、それ以外はfalse

変数.nil? =>true

Railsドキュメント

存在しないということ。

empty

空の文字列や空の配列の場合にtrueを返す。nilに対して呼び出すとNoMethodErrorが発生

変数.empty?

Railsドキュメント

Railsドキュメントにもはっきり書いてあ離ますが、nilに対して呼び出すとNoMethodErrorが発生するというように、配列などの箱があった状態でその中身が空であるとtrueになるみたい。

上記から考えられること

nil存在していないという意味であり、空の文字列ではないため、エラーになっているということになります。

じゃあどうすればいいのか…??

成功テスト

context "messageが空の時" do
      before do
        @note =Note.new(message: nil)
        @note.valid?
      end
      it "無効であること" do
        expect(@note.errors[:message]).to include("can't be blank")
      end
    end

@note.valid?で保存を失敗させる。

expect(@note.errors[:message]).to include("can't be blank")でmessageにエラーが含まれていることのような振舞いにしてあげればOKです!

まとめ

nilの値をemptyで検証するとエラーが起こる。

nilは、存在しないという意味

・emptyは、配列などの箱の中の空を示している。

nilを使ったテストを書く時は、valid?でエラーを表示されていることを期待するテストだと有効。

他にもわかりやすいテスト方法があったら是非コメントお待ちしています。

最後まで読んでいただきありがとうございました!

参考資料

https://railsdoc.com/active_support

https://qiita.com/somewhatgood@github/items/b74107480ee3821784e6