単体テスト(Rspec)

単体テストについて、あくまで自分が知っている範囲内で書いていきます。

##参考文献
https://leanpub.com/everydayrailsrspec-jp

https://qiita.com/jnchito/items/42193d066bd61c740612

https://qiita.com/jnchito/items/2e79a1abe7cd8214caa5

##単体テスト
主にモデルとコントローラで行う。
しかし、コントローラは統合テストで書けるので、今回はモデルの単体テストのみ書く。

モデルのテストで行うことは、モデルのファイルに記述したvalidatesなどが正しく機能しているかを確認する。

例えば、deviseをインストールしているとして、単体テストの骨組みとなる部分を書いていく。
まず、userモデルに記述している内容は、

```user.rb
validates :name, presence: true, length: { minimum: 2,maximum: 20}
validates :text, length: { maximum: 100}
```
1行目はnameが必ず必要で、その文字列の長さは2~20文字の間で設定すること。
２行目はtextの長さは100文字以内にすること。

次にテストファイルについて書く。
以下のように、大枠を決めてしまってテストを書いていく。

```spec/models/user_spec.rb
it "is valid with name, email and password" do

it "is not valid without name" do

it "is not valid without email" do

it "is not valid without password" do

it "has a valid factory" do
（factoryBotが機能しているかどうか）

it "is not valid when name length is 1" do

it "is valid when name length is 2" do

it "is not valid when name length is 21" do

it "is valid when name length is 20" do

it "is not valid when password length is 5" do

it "is valid when password length is 6" do

it "is not valid when text length is 101" do

it "is valid when text length is 100" do

```

ここでは境界値分析も合わせて行う。
境界値分析とは、例えばnameの文字数が2文字以上でなければならないのに対して、
１文字で設定するとエラーが出る、または２文字で設定するとpassする、といったことを行うテストのこと。

今回のテストでは、FactoryBotを使う。

```spec/factories.users.rb
FactoryBot.define do
  factory :user, aliases: [:owner] do
    name "kitchenからの私発信"
    text "やっぱり米が美味しい"
    sequence(:email) { |n| "tester#{n}@example.com"}
    password "dottle-nouveau-pavilion-tights-furze"
  end
end
```

テスト結果が以下の通り。

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

RSpec.describe User, type: :model do
  it "is valid with name, email and password" do
    user = FactoryBot.build(:user, text: nil)
    expect(user).to be_valid
  end

  it "is not valid without name" do
    user = FactoryBot.build(:user, name: nil)
    user.valid?
    expect(user.errors[:name]).to include("can't be blank")
  end

  it "is not valid without email" do
    user = FactoryBot.build(:user, email: nil)
    user.valid?
    expect(user.errors[:email]).to include("can't be blank")
  end

  it "is not valid without password" do
    user = FactoryBot.build(:user, password: nil)
    user.valid?
    expect(user.errors[:password]).to include("can't be blank")
  end

  it "has a valid factory" do
    expect(FactoryBot.build(:user)).to be_valid
  end

  it "is not valid when name length is 1" do
    user = FactoryBot.build(:user, name: "a")
    user.valid?
    expect(user.errors[:name]).to include("is too short (minimum is 2 characters)")
  end

  it "is valid when name length is 2" do
    user = FactoryBot.build(:user, name: "a"*2)
    user.valid?
    expect(user).to be_valid
  end

  it "is not valid when name length is 21" do
    user = FactoryBot.build(:user, name: "a"*21)
    user.valid?
    expect(user.errors[:name]).to include("is too long (maximum is 20 characters)")
  end

  it "is valid when name length is 20" do
    user = FactoryBot.build(:user, name: "a"*20)
    user.valid?
    expect(user).to be_valid
  end

  it "is not valid when password length is 5" do
    user = FactoryBot.build(:user, password: "a"*5)
    user.valid?
    expect(user.errors[:password]).to include("is too short (minimum is 6 characters)")
  end

  it "is valid when password length is 6" do
    user = FactoryBot.build(:user, password: "a"*6)
    user.valid?
    expect(user).to be_valid
  end

  it "is not valid when text length is 101" do
    user = FactoryBot.build(:user, text: "a"*101)
    user.valid?
    expect(user.errors[:text]).to include("is too long (maximum is 100 characters)")
  end

  it "is valid when text length is 100" do
    user = FactoryBot.build(:user, text: "a"*100)
    user.valid?
    expect(user).to be_valid
  end

end
```