rspec 基本まとめ　伊藤さんの記事より抜粋

## 基本な部分の理解だけにフォーカスしたまとめ

### 出てくる用語& メソッド

- befoe（前処理、共通処理をまとめる）
- let, shared_context
- exoect,to be_valid, eq（評価メソッド）
- describe, context, it（ネームスペース的な役割）

### 関連

letなどは下記にまとめる
https://qiita.com/tech-aki/items/0fcb9fa5e0f0bd5ec3b4

## サンプル

### テストするクラス

userが年齢によって、挨拶の仕方が、`漢字`か`ひらがな`に変わるメソッド


```ruby
class User
  def initialize(name:, age:)
    @name = name
    @age = age
  end
  def greet
    if @age <= 12
      "ぼくは#{@name}だよ。"
    else
      "僕は#{@name}です。"
    end
  end
end
```

### テストファイル


```ruby:一旦のゴール
RSpec.describe User do
  describe '#greet' do
    before do
      @params = { name: 'たろう' }
    end
    context '12歳以下の場合' do
      before do
        @params.merge!(age: 12)
      end
      it 'ひらがなで答えること' do
        user = User.new(@params)
        expect(user.greet).to eq 'ぼくはたろうだよ。'
      end
    end
    context '13歳以上の場合' do
      before do
        @params.merge!(age: 13)
      end
      it '漢字で答えること' do
        user = User.new(@params)
        expect(user.greet).to eq '僕はたろうです。'
      end
    end
  end
end
```

### めっちゃ何も考えないで書く

```ruby
RSpec.describe User do
  describe "#greet" do
    it "12才以上の場合漢字" do
      user = User.new(name: "たろう", age:12)
      expect(user.greet).to eq("僕はたろうだよ")
    end

    it "12才以下のひらがな" do
      user = user = User.new(name:"たろう", age:11)
      expect(user.greet).to eq("ぼくはたろうだよ")
    end
  end
end
```

### ネームスペースを使う。`conetext`


下記では`12才以上か以下`かで切り分けている

```ruby
RSpec.describe User do
  describe "#greet" do
    context "12才以上の場合" do
      it "漢字" do
        user = User.new(name: "たろう", age:12)
        expect(user.greet).to eq("僕はたろうだよ")
      end
    end

    context "12才以下の場合" do
      it "ひらがな" do
        user = user = User.new(name:"たろう", age:11)
        expect(user.greet).to eq("ぼくはたろうだよ")
      end
    end
  end
end
```

### 共通の前処理はまとめる`before_ver1`でまとめる

`name: "たろう"`が重複しているので、`before do; end`にかける。


`params`の書き方は`merge`するパターンと'params[:name]'の両方で書きましたが、本家は`params.merge(age: 12)`の書き方




```ruby:before_ver1

RSpec.describe User do
  describe "#greet" do
    before do
     @params = {name:"たろう"}
    end
    context "12才以上の場合" do
      it "漢字" do
        user = User.new(@params[:name], age:12)
        expect(user.greet).to eq("僕はたろうだよ")
      end
    end

    context "12才以下の場合" do
      it "ひらがな" do
        user = user = User.new(@params.merge(age:11))
        expect(user.greet).to eq("ぼくはたろうだよ")
      end
    end
  end
end

```


### スコープを意識した`before_ver2`の使い方


`describe`のスコープの中と`context`のスコープの中で`before`の使い方が異なる

`describe`の`before`が`漢字`と`ひらがな`のテストの両方で使う、`name: "たろう"`
`context`の`before`は`age`で`context`の中で別に使う



```ruby:before_ver2

RSpec.describe User do
  describe "#greet" do
    before do
     @params = {name:"たろう"}
    end
    context "12才以上の場合" do
      before do
        @params.merge(age:12)
      end
      it "漢字" do
        user = User.new(@params)
        expect(user.greet).to eq("僕はたろうだよ")
      end
    end

    context "12才以下の場合" do
      before do
        @params.merge(age:11)
      end
      it "ひらがな" do
        user = user = User.new(@params)
        expect(user.greet).to eq("ぼくはたろうだよ")
      end
    end
  end
end
```


## let


```ruby
    34:
    35:     context "12才以下の場合" do
    36:
    37:       let(:params){{name:"太郎", age:11}}
    38:       it "ひらがな" do
 => 39:         binding.pry
    40:         user = user = User.new(params)
    41:         expect(user.greet).to eq("ぼくはたろうだよ")
    42:       end
    43:     end
    44:   end

[1] pry(#<RSpec::ExampleGroups::User::Greet::Nested12_2>)> params
=> {:name=>"太郎", :age=>11}
```

## shared_context

```ruby
# ageは ageと呼ぶと 12がreturnされる

RSpec.describe User do

  describe "#greet" do
    shared_context 'hello' do
      let(:age){12}
      let(:params){{name:"太郎",age: age}}
    end

    context "12才以上の場合" do
      include_context "hello"
      it "漢字" do
        user = User.new(params)
        expect(user.greet).to eq("僕は太郎だよ")
      end
    end

    context "12才以下の場合" do

      include_context "hello"
      it "ひらがな" do
        user = user = User.new(params)
        expect(user.greet).to eq("僕は太郎だよ")
      end
    end
  end
end

```


### 参考記事

伊藤淳一さんの記事

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