我有以下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
?
答案 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