LoginSignup
14
14

More than 5 years have passed since last update.

あれやこれやしたRailsのモデル用Specファイル その2

Posted at

# -*- coding: utf-8 -*-
require 'spec_helper'

describe Team do

  let(:valid_model) { FactoryGirl.build(:team_base) }
  let(:created_model) { FactoryGirl.create(:team_base) }

  # idで抽出できることを確認する
  shared_examples_for :can_find_by_team_id do |id|
    it {->{Team.find(id)}.should_not raise_error(ActiveRecord::RecordNotFound)}
  end

  # idで抽出できないことを確認する
  shared_examples_for :can_not_find_by_team_id do |id|
    it {->{Team.find(id)}.should raise_error(ActiveRecord::RecordNotFound)}
  end

  # 属性の値を変更したらinvalid?がfalseからtrueになることを確認する
  shared_examples_for :to_invalid_after_attr_change do |name, test_values|
    describe name do
      test_values.each do |label, value|
        context "set '#{value}'(#{label.to_s})" do
          subject { target_model }
          it { ->{ subject[name] = value}.should change(subject, :invalid?).from(false).to(true)}
        end
      end
    end
  end

  # インスタンス生成直後は保存できない
  context 'when new' do
    subject{ Team.new }
    its(:valid?) { should_not be_true }
    its(:save) { should be_false}
  end

  # 以降で使用する保存可能なモデルが本当に保存できるか確認
  describe 'valid model' do
    subject { valid_model }
    its(:valid?) { should be_true }
    its(:save) { should be_true }
  end

  context 'after save' do
    # 保存したら1件増える
    it { ->{ created_model }.should change(Team, :count).by(1) }
    # 抽出できること
    it_behaves_like :can_find_by_team_id, FactoryGirl.create(:team_base).id
  end

  context 'after delete' do
    # let!はbefore(:each)みたいに各サンプルの前に実行される
    let!(:target) { FactoryGirl.create(:team_base) }

    # 削除されたら1件減る
    it { ->{ target.delete }.should change(Team, :count).by(-1) }
    # 抽出できないこと
    it_behaves_like :can_not_find_by_team_id, FactoryGirl.create(:team_base).delete.id
  end

  context 'after destroy' do
    let!(:target) { FactoryGirl.create(:team_base, member_count: 10) }

    it {->{ target.destroy }.should change(Team, :count).by(-1) }
    it_behaves_like :can_not_find_by_team_id, FactoryGirl.create(:team_base).destroy.id
  end

  # validatesをまとめて確認
  describe 'attributes' do

    test_values = {empty: '', length_over: 'あいうえおあいうえおあいうえおあいうえおあ'}

    it_behaves_like :to_invalid_after_attr_change , 'name', test_values do
      let(:target_model) { valid_model }
    end

  end

  describe 'members attribute' do

    context 'can add new member' do
      subject { created_model }
      let!(:new_member) { FactoryGirl.create(:player) }
      it { ->{ subject.add_member(new_member) }.should change(subject.members, :count).by(1) }
    end

    context 'can remove a member' do
      subject { created_model }
      let!(:new_member) { FactoryGirl.create(:player) }
      let!(:member_add) { subject.add_member(new_member); subject }
      it { ->{ member_add.remove_member(new_member) }.should change(subject.members, :count).by(-1) }
    end

    context 'after destroy' do
      let!(:target) { FactoryGirl.create(:team_base, member_count: 10) }
      let!(:members_count) { target.members.count }
      it {->{ target.destroy }.should change(target.members, :count).from(members_count).to(0)}
    end

  end

  describe 'players method' do
    context 'add 5 players' do
      before do
        @team = FactoryGirl.create(:team_base, add_manager: false)
        players = FactoryGirl.create_list(:player, 5)
        players.each { |p| @team.add_member(p) }
      end

      subject { @team }
      let!(:players_count) { subject.members.find_all_by_member_type(Member::MemberTypes[:player]).count }
      its('players.count') { should == players_count}
    end
  end

  describe 'managers method' do
    context 'add 5 managers' do
      before do
        @team = FactoryGirl.create(:team_base, add_manager: false)
        managers = FactoryGirl.create_list(:manager, 5)
        managers.each { |p| @team.add_member(p) }
      end

      subject { @team }
      let!(:managers_count) { subject.members.find_all_by_member_type(Member::MemberTypes[:manager]).count }
      its('managers.count') { should == managers_count }
    end
  end
end
14
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
14