web-dev-qa-db-ja.com

Railsで懸念をテストする方法

私のRails 4アプリケーションにPersonable懸念がある場合、full_nameメソッド、RSpecを使用してこれをテストするにはどうすればよいですか?

concerns/personable.rb

module Personable
  extend ActiveSupport::Concern

  def full_name
    "#{first_name} #{last_name}"
  end
end
95
Kyle Decot

見つけたメソッドは確かに少しの機能をテストするために機能しますが、かなり壊れやすいようです。ダミークラス(実際にはソリューション内のStruct)は、includesあなたの懸念。さらに、モデルの懸念をテストしようとしている場合、それに応じてデータベースをセットアップしない限り、オブジェクトの有効性をテストしたり、ActiveRecordコールバックを呼び出したりすることはできません(ダミークラスにはデータベーステーブルバッキングがないため)それ)。さらに、懸念事項をテストするだけでなく、モデル仕様内の懸念事項の動作もテストする必要があります。

では、1石で2羽の鳥を殺してみませんか? RSpecの 共有サンプルグループ を使用することにより、それらを使用する実際のクラス(モデルなど)に対する懸念をテストできますandそれらが使用されているすべての場所でテストできます。また、テストを1回作成するだけで、懸念事項を使用するモデル仕様にテストを含めるだけで済みます。あなたの場合、これは次のようになります。

# app/models/concerns/personable.rb

module Personable
  extend ActiveSupport::Concern

  def full_name
    "#{first_name} #{last_name}"
  end
end

# spec/concerns/personable_spec.rb

require 'spec_helper'

shared_examples_for "personable" do
  let(:model) { described_class } # the class that includes the concern

  it "has a full name" do
    person = FactoryBot.build(model.to_s.underscore.to_sym, first_name: "Stewart", last_name: "Home")
    expect(person.full_name).to eq("Stewart Home")
  end
end

# spec/models/master_spec.rb

require 'spec_helper'
require Rails.root.join "spec/concerns/personable_spec.rb"

describe Master do
  it_behaves_like "personable"
end

# spec/models/apprentice_spec.rb

require 'spec_helper'

describe Apprentice do
  it_behaves_like "personable"
end

このアプローチの利点は、ARオブジェクトよりも小さいものではできないARコールバックの呼び出しなど、関心のあることを始めるとさらに明白になります。

159
Josh Leitzel

私が受け取ったコメントに応えて、私がやったことは次のとおりです(誰かが改善した場合は気軽に投稿してください)

spec/concerns/personable_spec.rb

require 'spec_helper'

describe Personable do
  let(:test_class) { Struct.new(:first_name, :last_name) { include Personable } }
  let(:personable) { test_class.new("Stewart", "Home") }

  it "has a full_name" do
    expect(personable.full_name).to eq("#{personable.first_name} #{personable.last_name}")
  end
end
55
Kyle Decot

別の考えは、 with_model gem を使用してこのようなことをテストすることです。私は自分で懸念をテストしようとしていて、 pg_search gemこれを行う を見ていました。個々のモデルをテストするよりもはるかに優れているようです。モデルが変更される可能性があるためです。また、仕様で必要になるものを定義するのは良いことです。

5
lobati