O método que você encontrou certamente funcionará para testar um pouco de funcionalidade, mas parece muito frágil - sua classe fictícia (na verdade, apenas a Struct
em sua solução) pode ou não se comportar como uma classe real que include
é a sua preocupação. Além disso, se você estiver tentando testar as preocupações do modelo, não será capaz de fazer coisas como testar a validade de objetos ou invocar retornos de chamada ActiveRecord a menos que configure o banco de dados de acordo (porque sua classe fictícia não terá um suporte de tabela de banco de dados isto). Além disso, você desejará não apenas testar a preocupação, mas também testar o comportamento da preocupação dentro das especificações do seu modelo.
Então, por que não matar dois coelhos com uma cajadada só? Usando os grupos de exemplos compartilhados do RSpec , você pode testar suas preocupações em relação às classes reais que os usam (por exemplo, modelos) e poderá testá-los em todos os lugares em que são usados. E você só precisa escrever os testes uma vez e depois incluí-los em qualquer especificação de modelo que use sua preocupação. No seu caso, pode ser algo assim:
# 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
As vantagens dessa abordagem se tornam ainda mais óbvias quando você começa a fazer coisas em sua preocupação, como invocar callbacks de AR, onde qualquer coisa menos do que um objeto AR simplesmente não funcionará.