Ecco un altro esempio (usando del factorygirl "creare" metodo" e shared_examples_for)
preoccupazione spec
#spec/support/concerns/commentable_spec
require 'spec_helper'
shared_examples_for 'commentable' do
let (:model) { create (described_class.to_s.underscore) }
let (:user) { create (:user) }
it 'has comments' do
expect { model.comments }.to_not raise_error
end
it 'comment method returns Comment object as association' do
model.comment(user, "description")
expect(model.comments.length).to eq(1)
end
it 'user can make multiple comments' do
model.comment(user, "description")
model.comment(user, "description")
expect(model.comments.length).to eq(2)
end
end
commentabile preoccupazione
module Commentable
extend ActiveSupport::Concern
included do
has_many :comments, as: :commentable
end
def comment(user, description)
Comment.create(commentable_id: self.id,
commentable_type: self.class.name,
user_id: user.id,
description: description
)
end
end
e restraunt_spec possono sembrare qualcosa del genere (I'm n ot Rspec guru quindi non credo che il mio modo di scrivere le specifiche è buona - la cosa più importante è all'inizio):
require 'rails_helper'
RSpec.describe Restraunt, type: :model do
it_behaves_like 'commentable'
describe 'with valid data' do
let (:restraunt) { create(:restraunt) }
it 'has valid factory' do
expect(restraunt).to be_valid
end
it 'has many comments' do
expect { restraunt.comments }.to_not raise_error
end
end
describe 'with invalid data' do
it 'is invalid without a name' do
restraunt = build(:restraunt, name: nil)
restraunt.save
expect(restraunt.errors[:name].length).to eq(1)
end
it 'is invalid without description' do
restraunt = build(:restraunt, description: nil)
restraunt.save
expect(restraunt.errors[:description].length).to eq(1)
end
it 'is invalid without location' do
restraunt = build(:restraunt, location: nil)
restraunt.save
expect(restraunt.errors[:location].length).to eq(1)
end
it 'does not allow duplicated name' do
restraunt = create(:restraunt, name: 'test_name')
restraunt2 = build(:restraunt, name: 'test_name')
restraunt2.save
expect(restraunt2.errors[:name].length).to eq(1)
end
end
end
fonte
2015-06-11 12:49:56
Questa è chiaramente la migliore risposta. Uno può essere esplicito nel caso Dummy E testare la stessa API nelle specifiche della classe genitore. Questo fa la differenza quando si ha a che fare con qualsiasi API "flessibile" (leggi: method_missing). Ci sono semplicemente alcuni casi a cui non si può pensare fino a quando non sono in uso in una classe "reale" (non fittizia), e gli esempi condivisi faranno un buon lavoro nell'esercitare il codice in ogni contesto necessario. – winfred
Si verifica quando il modulo aggiunge attributi dinamici. Supponiamo che il tuo modulo permetta il metodo di classe: 'allow_upload: csv', che aggiunge metodi come' csv_file_path' e 'csv_file_size'. Ma hai un altro modello che chiama il file caricato ': attachment'. Ora la tua specifica "agisce come upload" fallirà perché uno sta aggiungendo 'csv_file_path' e uno ha' attachment_file_path'.Per questo motivo mi sento come se in molti casi andasse meglio per le tue esigenze utilizzare una classe fittizia per testare il comportamento del modulo come nella risposta di @Martijn – nzifnab
@nzifnab per essere chiari, il modulo non sta aggiungendo il metodo, la classe bambino è esplicitamente. Se gli esempi condivisi sono appropriati, ecco una chiamata di giudizio specifica per la base di codice. Tuttavia, puoi ancora usarli in questo modo. È possibile passare le informazioni a loro, proprio come nella chiamata: 'it_behaves_like 'funge da upload',: csv' –