Как работает 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