121

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

懸念/personable.rb

module Personable
  extend ActiveSupport::Concern

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

5 に答える 5

199

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

では、一石二鳥ではないでしょうか。RSpec の共有サンプル グループを使用することで、それらを使用する実際のクラス (モデルなど) に対して懸念事項をテストでき、それらが使用されているすべての場所テストできます。また、テストを 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 オブジェクト以外では機能しないようなことを懸念事項で実行し始めると、さらに明らかになります。

于 2013-11-15T21:29:06.103 に答える
1

以下は私のために働いた。私の場合、私の懸念は生成された * _pathメソッドを呼び出すことであり、他のアプローチは機能していないようでした。このアプローチにより、コントローラーのコンテキストでのみ使用可能なメソッドの一部にアクセスできるようになります。

懸念:

module MyConcern
  extend ActiveSupport::Concern

  def foo
    ...
  end
end

仕様:

require 'rails_helper'

class MyConcernFakeController < ApplicationController
  include MyConcernFakeController
end

RSpec.describe MyConcernFakeController, type: :controller do    
  context 'foo' do
    it '' do
      expect(subject.foo).to eq(...)
    end
  end
end
于 2021-06-02T03:14:02.120 に答える