Как работает be_some в RSpec?
November 24, 2014

Как-то раз я решил разобраться какая именно магия используется в RSpec-предикаторах be_some, так
как на первый взгляд они напоминают undefined local variable or method.
class Sun
def available?
false
end
end
describe Sun do
it "sad and cold" do
expect(Sun.new).not_to be_available
end
end
Конечно же это method_messing. Продираться через все хитросплетения RSpec мне не захотелось, хотя
код там очень основательный и щедро документированный, я нашел лишь несколько ключевых точек.
describe Sun превращается в класс RSpec::ExampleGroups::Sun, наследованный от
RSpec::Core::ExampleGroup, в который при инициализации подмешивается модуль RSpec::Matchers ,
отлавливающий be_* с помощью method_messing .
module RSpec
# ...
module Matchers
# ...
BE_PREDICATE_REGEX = /^(be_(?:an?_)?)(.*)/
HAS_REGEX = /^(?:have_)(.*)/
def method_missing(method, *args, &block)
case method.to_s
when BE_PREDICATE_REGEX
BuiltIn::BePredicate.new(method, *args, &block)
when HAS_REGEX
BuiltIn::Has.new(method, *args, &block)
else
super
end
end
Отлично, теперь можно спать спокойно.
Tweet