Rspec如何判断一个let块是否已经定义?

Rspec how to determine if a let block has been defined?

在 Rspec 中,我想利用 super() 调用已定义的 let 块(如果存在)或设置新值(如果不存在),我想在 shared_example 组中使用此功能,但我找不到如何执行此操作。

我试过检查 @some_let 是否存在,我试过检查 :some_let 的超级方法是否由 kernel 和 none 拥有他们提供任何有用的东西;我无法访问 instance_methodsinstance_method,因为 Rspec 不允许我访问,并且在互联网上搜索方法也没有找到答案。

我希望能够做这样的事情:

shared_examples 'a shared example' do
  let(:some_let) { let_exists?(:some_let) ? super() : some_new_value }
end

是否有类似 let_exists? 的方法或类似的方法?

假设您在包含共享示例之前调用 let,这将有效:

shared_examples 'a shared example' do
  let(:some) { 'fallback value' } unless method_defined?(:some)
end

describe 'with let' do
  let(:some) { 'explicit value' }
  include_examples 'a shared example'

  it { expect(some).to eq('explicit value') }
end

describe 'without let' do
  include_examples 'a shared example'

  it { expect(some).to eq('fallback value') }
end

method_defined? 检查是否已在当前上下文中定义名为 some 的方法。如果不是,则定义该方法以提供默认值。

另一种(通常更简单的)方法是始终定义默认值并在 之后提供显式值,包括共享示例:(从而覆盖默认值)

shared_examples 'a shared example' do
  let(:some) { 'default value' }
end

describe 'with let' do
  include_examples 'a shared example'   # <- order is
  let(:some) { 'explicit value' }       #    important

  it { expect(some).to eq('explicit value') }
end

describe 'without let' do
  include_examples 'a shared example'

  it { expect(some).to eq('default value') }
end