はじめに
concerns
で実装はすっきりしたんだけど、minitest
でテストを書くときにどうするんだっけ?と困った。rspec
に入れ替えてshared_examples
使おうという声が聞こえるけどたぶん錯覚なんだ。
実装サンプル
こんな感じのサンプルがありまして...
class SampleModel < ActiveRecord::Base
include SampleConcern
# name attribute defined
end
module SampleConcern
extend ActiveSupport::Concern
included do
# concernsに実装するのはたぶん不適切だけど
validate name, presence: true
end
def greet
"I'm #{name}"
end
end
テスト
SampleConcern
がActiveRecord
に依存しない(has_many
とかvalidates
が書いていない)場合はただのmodule
なので、テスト用クラスを作ってinclude
してやれば済む。
大人の事情により、依存しているクラスをテストする場合は以下のコードでテストが書ける。
(module
側のsetup
をincluded
の中に定義することでテストクラスのsuper
呼び出しを省略できるがケースバイケース)
require 'test_helper'
require 'models/sample_concern_test'
class SampleModelTest < ActiveSupport::TestCase
include SampleConcernTest
def setup
super
end
private
def test_instance
SampleModel.new
end
end
module SampleConcernTest
extend ActiveSupport::Concern
def setup
@my_sample = test_instance
end
included do
test "correct name greeting" do
name = "paty"
@my_sample.name = name
assert_equal "I'm #{name}", @my_sample.greet
end
end
private
def test_instance
raise NotImplementedError.new("override with InheritanceClass.new")
end
end