Metoda, którą znalazłeś, z pewnością zadziała, aby przetestować trochę funkcjonalności, ale wydaje się dość krucha - twoja fikcyjna klasa (właściwie tylko Struct
w twoim rozwiązaniu) może zachowywać się jak prawdziwa klasa, ale nie musi include
. Dodatkowo, jeśli próbujesz przetestować obawy dotyczące modelu, nie będziesz mógł wykonywać takich czynności, jak testowanie poprawności obiektów lub wywoływanie wywołań zwrotnych ActiveRecord, chyba że odpowiednio skonfigurujesz bazę danych (ponieważ twoja fikcyjna klasa nie będzie miała kopii zapasowej tabeli bazy danych to). Co więcej, będziesz chciał nie tylko przetestować problem, ale także przetestować jego zachowanie w specyfikacji modelu.
Dlaczego więc nie upiec dwóch pieczeni na jednym ogniu? Używając wspólnych przykładowych grup RSpec , możesz sprawdzić swoje obawy w odniesieniu do klas, które ich używają (np. Modeli) i przetestować je wszędzie tam, gdzie są używane. I wystarczy tylko raz napisać testy, a następnie po prostu uwzględnić je w specyfikacji dowolnego modelu, która wykorzystuje Twoje obawy. W twoim przypadku może to wyglądać mniej więcej tak:
# 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
Zalety tego podejścia stają się jeszcze bardziej oczywiste, gdy zaczynasz robić rzeczy w swoim problemie, takie jak wywoływanie wywołań zwrotnych AR, gdzie nic mniej niż obiekt AR po prostu nie zadziała.