模块 Minitest::Spec::DSL

看!一个 Minitest::Spec::DSL 模块!让 DHH 羡慕去吧。

常量

TYPES

包含匹配器和 Spec 类的配对,用于计算顶层 describe 的超类。这允许自动自定义 spec 类型。

参见:register_spec_typespec_type

公共实例方法

after(_type = nil, &block) 点击切换源码

定义一个 'after' 操作。继承方式与普通方法相同。

注意:type 被忽略,仅为了方便移植而存在。

等效于 Minitest::Test#teardown

调用超类方法
# File minitest-5.25.4/lib/minitest/spec.rb, line 206
def after _type = nil, &block
  define_method :teardown do
    self.instance_eval(&block)
    super()
  end
end
before(_type = nil, &block) 点击切换源码

定义一个 'before' 操作。继承方式与普通方法相同。

注意:type 被忽略,仅为了方便移植而存在。

等效于 Minitest::Test#setup

调用超类方法
# File minitest-5.25.4/lib/minitest/spec.rb, line 192
def before _type = nil, &block
  define_method :setup do
    super()
    self.instance_eval(&block)
  end
end
it(desc = "anonymous", &block) 点击切换源码

定义一个名为 desc 的期望。名称会被变形为正确的测试方法名称。出于某些奇怪的原因,编写 spec 的人不怎么喜欢类继承,因此这里会不遗余力地确保期望不会被继承。

这也别名为 specify,并且不需要 desc 参数。

提示:如果您确实想要继承,请使用 minitest/test。您可以在断言和期望之间随意混合搭配。

# File minitest-5.25.4/lib/minitest/spec.rb, line 224
def it desc = "anonymous", &block
  block ||= proc { skip "(no tests defined)" }

  @specs ||= 0
  @specs += 1

  name = "test_%04d_%s" % [ @specs, desc ]

  undef_klasses = self.children.reject { |c| c.public_method_defined? name }

  define_method name, &block

  undef_klasses.each do |undef_klass|
    undef_klass.send :undef_method, name
  end

  name
end
也别名为:specify
let(name, &block) 点击切换源码

本质上,为 name 定义一个带有 block 的访问器。

为什么使用 let 而不是 def?我真的不知道。

# File minitest-5.25.4/lib/minitest/spec.rb, line 248
def let name, &block
  name = name.to_s
  pre, post = "let '#{name}' cannot ", ". Please use another name."
  methods = Minitest::Spec.instance_methods.map(&:to_s) - %w[subject]
  raise ArgumentError, "#{pre}begin with 'test'#{post}" if
    name.start_with? "test"
  raise ArgumentError, "#{pre}override a method in Minitest::Spec#{post}" if
    methods.include? name

  define_method name do
    @_memoized ||= {}
    @_memoized.fetch(name) { |k| @_memoized[k] = instance_eval(&block) }
  end
end
register_spec_type(*args, &block) 点击切换源码

注册一个新的 spec 类型,该类型与 spec 的描述匹配。此方法可以接受正则表达式和 spec 类,也可以接受 spec 类和一个块,该块接受描述并在匹配时返回 true。

例如

register_spec_type(/Controller$/, Minitest::Spec::Rails)

register_spec_type(Minitest::Spec::RailsModel) do |desc|
  desc.superclass == ActiveRecord::Base
end
# File minitest-5.25.4/lib/minitest/spec.rb, line 147
def register_spec_type *args, &block
  if block then
    matcher, klass = block, args.first
  else
    matcher, klass = *args
  end
  TYPES.unshift [matcher, klass]
end
spec_type(desc, *additional) 点击切换源码

根据 spec 的描述找出要使用的 spec 类。例如

spec_type("BlahController") # => Minitest::Spec::Rails
# File minitest-5.25.4/lib/minitest/spec.rb, line 161
def spec_type desc, *additional
  TYPES.find { |matcher, _klass|
    if matcher.respond_to? :call then
      matcher.call desc, *additional
    else
      matcher === desc.to_s
    end
  }.last
end
specify(desc = "anonymous", &block)
别名:it
subject(&block) 点击切换源码

另一个懒人访问器生成器。通过将名称设置为 subject 而变得更加懒惰。

# File minitest-5.25.4/lib/minitest/spec.rb, line 267
def subject &block
  let :subject, &block
end