RSpec模拟,“名称”在示例组

时间:2017-08-01 13:45:48

标签: ruby rspec

我有以下Ruby代码:

def report_deviation(departure)
  deviation = departure.fetch('Dev')
  trip = departure.fetch('Trip')
  run_id = trip.fetch('RunId')
  headsign = trip.fetch('InternetServiceDesc')
  timestamp = Time.now.strftime '%l:%M %P'
  FileUtils.mkdir 'log' unless File.directory? 'log'
  File.open DAILY_LOG_FILE, 'a' do |file|
    file.puts "#{timestamp}, #{name}: Run #{run_id} (#{headsign}), deviation #{deviation}"
  end
end

通过以下RSpec代码测试:

describe 'report_deviation' do
  let(:departure) { double }
  let(:trip) { double }
  let(:file) { double }
  it 'appends to a log file with the correct entry format' do
    expect(departure).to receive(:fetch).with('Trip').and_return trip
    expect(departure).to receive(:fetch).with('Dev').and_return 'DEVIATION'
    expect(trip).to receive(:fetch).with('RunId')
      .and_return 'RUN'
    expect(trip).to receive(:fetch).with('InternetServiceDesc')
      .and_return 'HEADSIGN'
    stub_const 'DeviationValidator::DAILY_LOG_FILE', :log_file
    expect(File).to receive(:open).with(:log_file, 'a').and_yield file
    timestamp = '12:00 pm: Run RUN (HEADSIGN), deviation DEVIATION'
    expect(file).to receive(:puts).with timestamp
    Timecop.freeze(Time.new 2017, 7, 31, 12) { report_deviation(departure) }
  end
end

但是当我跑步时,我收到了失败的消息:

`name` is not available from within an example (e.g. an `it` block) or from constructs that run in the scope of an example (e.g. `before`, `let`, etc). It is only available on an example group (e.g. a `describe` or `context` block).

单词name不会写在这里的任何地方,如果我删除测试的最后一行(调用实际代码),我会得到测试失败,我会期望不满意的异常。我通常会把我的代码煮到导致错误的部分,但我不知道导致错误的是什么。

对于它的价值,回溯中提到的特定行号是file.puts块中的File.open - 但我不明白为什么会导致失败。我已经设置了测试双打,这些对象没有什么特别之处 - File接收open并产生file,其唯一的工作是听取接收puts字符串我预计。那么什么代码调用的是关键字RSpec方法name

2 个答案:

答案 0 :(得分:2)

name不是关键字RSpec方法,它是report_deviation试图调用的方法

file.puts "#{timestamp}, #{name}: Run #{run_id} (#{headsign}), deviation #{deviation}"

但该方法未定义。

您需要在定义name的类中定义report_deviation方法。或者,如果在规范文件中定义并使用了report_deviation,请添加一个名为name的简单变量:

describe 'report_deviation' do
  let(:departure) { double }
  let(:trip) { double }
  let(:file) { double }
  let(:name) { "simple name" }
  ...

答案 1 :(得分:1)

<块引用>

`name` 在示例中不可用(例如 `it` 块)[...]

我今天遇到了类似的问题。目前该问题的最终解决方案是使用monkeypatch 返回使用method_name。

创建 config/initializers/monkeypatches.rb 文件并在里面填写以下几行。

# config/initializers/monkeypatches.rb
#
# This fixes what seems to be a bug introduced by
# https://github.com/rails/rails/pull/37770
# "Modify ActiveRecord::TestFixtures to not rely on AS::TestCase:"
#
module ActiveRecord::TestFixtures
  def run_in_transaction?
    use_transactional_tests &&
      !self.class.uses_transaction?(method_name) # this monkeypatch changes `name` to `method_name`
  end
end

信用:https://github.com/graphql-devise/graphql_devise/issues/42