Come faccio a scrivere i metodi che inseriscono esempi RSpec?
-
09-10-2019 - |
Domanda
In un gruppo di rotaie RSpec Specifiche unità che faccio qualcosa di simile:
describe Foo do
[:bar, :baz].each do |a|
it "should have many #{a}" do
Foo.should have_many(a)
end
end
end
Per il codice più pulito Preferirei fare qualcosa di simile:
describe Foo do
spec_has_many Foo, :bar, :baz
end
Quindi, come faccio a scrivere un metodo di supporto come spec_has_many()
per l'inserimento di codice DSL come metodo it()
di RSpec? Se fosse per un metodo di istanza ordinaria farei qualcosa di simile:
def spec_has_many(model, *args)
args.each do |a|
define_method("it_should_have_many_#{a}") do
model.should have_many(a)
end
end
end
Quale sarebbe l'equivalente per la definizione esempi RSpec?
Soluzione
Ok, questo ha preso un po 'di fare in giro, ma penso che ho preso a lavorare. E 'un po' di aggiustamenti metaprogrammazione, e io personalmente sarebbe solo usare la prima cosa che hai descritto, ma è quello che volevi: P
module ExampleMacros
def self.included(base)
base.extend(ClassMethods)
end
module ClassMethods
# This will be available as a "Class Macro" in the included class
def should_have_many(*args)
args.each do |a|
# Runs the 'it' block in the context of the current instance
instance_eval do
# This is just normal RSpec code at this point
it "should have_many #{a.to_s}" do
subject.should have_many(a)
end
end
end
end
end
end
describe Foo do
# Include the module which will define the should_have_many method
# Can be done automatically in RSpec configuration (see below)
include ExampleMacros
# This may or may not be required, but the should_have_many method expects
# subject to be defined (which it is by default, but this just makes sure
# it's what we expect)
subject { Foo }
# And off we go. Note that you don't need to pass it a model
should_have_many :a, :b
end
I miei spec fallire perché Foo non ha un metodo has_many?
, ma entrambi i test eseguito, così dovrebbe funzionare.
È possibile definire (e rinominare) il modulo ExampleMacros nel file spec_helper.rb
e sarà disponibile per l'inclusione. Si desidera chiamare include ExampleMacros
nei vostri blocchi describe
(e non tutti gli altri).
Per rendere tutte le specifiche includono il modulo automaticamente, configura RSpec in questo modo:
# RSpec 2.0.0
RSpec.configure do |c|
c.include ExampleMacros
end