[RSpec]コメント機能の単体テスト

# はじめに
本記事では、コメント機能の単体テストのコードや説明を記述します。

前回いいね機能について投稿しているので、こちらも参照ください。

https://qiita.com/mkato1013/items/3e36504e5f2648c91c88

## 前提
- コメント機能の実装ずみ
- 私は、投稿に対するコメントを実装しています。

# コード
早速ですが、コードを記述します。
初めの方のsleep 0.2は必要ありません。
自宅のWi-Fiがとんでもないぐらい遅いので記述しています。一応記事を添付します。

https://qiita.com/mkato1013/items/e7fd98978d90a0bad1a9


```spec/models/comment_spec.rb
require 'rails_helper'

RSpec.describe Comment, type: :model do
  before do
    user = FactoryBot.create(:user)
    food = FactoryBot.create(:food)
    @comment = FactoryBot.build(:comment, user_id: user.id, food_id: food.id)
    sleep 0.2
  end

  describe 'コメント機能' do
    context 'コメントを保存できる場合' do
      it "コメント文を入力済みであれば保存できる" do
        expect(@comment).to be_valid
      end
    end

    context 'コメントを保存できない場合' do
      it "コメントが空では投稿できない" do
        @comment.text = ''
        @comment.valid?
        expect(@comment.errors.full_messages).to include "Text can't be blank"
      end

      it "ユーザーがログインしていなければコメントできない" do
        @comment.user_id = nil
        @comment.valid?
        expect(@comment.errors.full_messages).to include "User must exist"
      end

      it "投稿したものがなければコメントできない" do
        @comment.food_id = nil
        @comment.valid?
        expect(@comment.errors.full_messages).to include "Food must exist"
      end
    end
  end
end
```
`text`はコメントするテキストのことです。ちょっと命名下手くそすぎたかな。。。

```comment.rb
FactoryBot.define do
  factory :comment do
    text        {'aaaa'}
    association :user
    association :food
  end
end
```
私の中でテストする項目は以下の４つだと思っています。

```
- コメント文を入力済みであれば保存できる
- コメントが空では投稿できない
- ユーザーがログインしていなければコメントできない
- 投稿したものがなければコメントできない
```
下２つのテストは、

```ruby
      it "ユーザーがログインしていなければコメントできない" do
        @comment.user_id = nil
        @comment.valid?
        expect(@comment.errors.full_messages).to include "User must exist"
      end

      it "投稿したものがなければコメントできない" do
        @comment.food_id = nil
        @comment.valid?
        expect(@comment.errors.full_messages).to include "Food must exist"
      end
```

FactoryBotのところで、
以下を記述します。

```ruby
    association :user
    association :food
```
さらに、以下を記述することでテストすることが可能になりました。

```spec/models/comment_spec.rb
  before do
    user = FactoryBot.create(:user)
    food = FactoryBot.create(:food)
    @comment = FactoryBot.build(:comment, user_id: user.id, food_id: food.id)
    sleep 0.2
  end
```

以上です。
いかがでしょうか。
どうにかテストできない場合は、空欄ではコメント送信できないようバリデーションできているかも確認してみます。


# 追記
@github0013@github さんからご意見いただき修正しました。ありがとうございます。

```comment.rb
FactoryBot.define do
  factory :comment do
    text             {'aaaa'}
    user
    food
  end
end
```

```spec/rails_helper.rb
RSpec.configure do |config|
  config.include FactoryBot::Syntax::Methods ←一番下の行に記述しました。
end
```

```spec/models/comment_spec.rb
  before do
    user = create(:user)
    food = create(:food)
    @comment = build(:comment, user_id: user.id, food_id: food.id)
    sleep 0.2
  end
```

```spec/rails_helper.rb
# Dir[Rails.root.join('spec', 'support', '**', '*.rb')].each { |f| require f }
↑コメントアウトする
```

また、一段と賢くなりました。

# 終わりに
テストは奥が深く、やればやるほど、また考えれば考えるほどどんどん浮かんできます。
作成されたアプリケーションもテストされている項目が多ければその分、使っていてバグが起こりにくいアプリケーションに仕上がるので、ここは注意できればなと考えました。

以下、参考サイトです。
[コメント機能　モデル単体テスト　実装](https://qiita.com/tmw9898/items/1cb2fbb0b7f2fd5d5164)

明日も頑張ります！！