为什么需要用 Cucumber DataTable 初始化 Cucumber DataTable?
Why do I need to initialize a Cucumber DataTable with a Cucumber DataTable?
我们最近开始更新一个非常古老的 Rails 应用程序(或至少不再过时)。其中一项更改是将 Cucumber 从 1.3.x 更新到 2.99.
我们关于此应用程序的许多 rspec 规范都使用了一个帮助程序来加载利用 Cucumber::Ast::DataTable
的测试数据。 (助手声明了它自己的继承自 Cucumber::Ast::DataTable
的子类。)这已被弃用,因此按照建议,我将继承替换为 Cucumber::MultilineArgument::DataTable
。
子类如下所示:
class ParsedTable < ::Cucumber::MultilineArgument::DataTable
def initialize(string)
super(string.split("\n").map do |line|
line = line.split('|').map(&:squish)
line.slice(1, line.length)
end)
end
end
然后有一堆测试助手可以像这样创建测试数据(假设 "role" 是我们要测试的模型):
def create_roles(string)
table = ParsedTable.new(string)
table.hashes.each do |hash|
create :role,
name: hash['Name'],
short_name: hash['Short Name'],
contracted_work_day: hash['Contracted workday in minutes']
end
end
这些助手是这样被调用的:
create_roles <<-eos
| Name | Contracted workday in minutes |
| Therapist | 390 |
eos
但是当那种电话打进来时,我得到 ArgumentError: data must be a Core::Ast::DataTable
。堆栈表示此异常来自 lib/cucumber/multiline_argument/data_table.rb:93:in 'initialize'
,这是 ParsedTable
定义中的 super
调用。
我一直在尝试围绕 Cucumber 来源追查此问题,但我无法弄清楚我做错了什么。
Cucumber 的 API 文档指出 Cucumber::MultilineArgument::DataTable 的构造函数采用 Core::Ast::DataTable
对象。
来源:https://www.rubydoc.info/gems/cucumber/Cucumber/MultilineArgument/DataTable#constructor_details
您将需要一个 Core::Ast::DataTable
的实例,而不是从字符串中自定义解析它。
Creates a new instance. +raw+ should be an Array of Array of String or an Array of Hash You don't typically create your own DataTable objects - Cucumber will do it internally and pass them to your Step Definitions.
来源:https://www.rubydoc.info/gems/cucumber-core/1.3.1/Cucumber/Core/Ast/DataTable#constructor_details
看起来 Cucumber 应该已经在步骤绑定中将 table 解析为 Core::Ast::DataTable
对象,因此您需要做的就是将其传递给 [= 的构造函数13=] class.
如果这不可用,则您需要提供一个字符串数组。
Greg Burghardt 的回答有其正确的理由; Cucumber::MultilineArgument::DataTable
class 需要一个 Core::Ast::DataTable
作为参数,而旧的 Cucumber::Ast::DataTable
则不是这样。 (这个 class 通常是 Cucumber 1.4.x 和当前版本之间的一个移动目标。)
最后我通过回避问题解决了这个问题。仔细查看使用自定义 ParsedTable
class 的方法,我发现它们并不真正依赖于 class,而是指望在每个实例上调用 hashes
。我需要的是对 hashes
做出适当回应的东西。
因此,我没有使用 subclassing Cucumber::MultilineArgument::DataTable
来获取自定义构造函数,而是用接受字符串的方法替换了 subclass 定义,将其拆分为行,并将 Array
行馈送到 Cucumber::MultilineArgument::DataTable#from
。这返回了一个 Cucumber::MultilineArgument::DataTable
的实例,我可以在其上调用 hashes
。那行得通。
我们最近开始更新一个非常古老的 Rails 应用程序(或至少不再过时)。其中一项更改是将 Cucumber 从 1.3.x 更新到 2.99.
我们关于此应用程序的许多 rspec 规范都使用了一个帮助程序来加载利用 Cucumber::Ast::DataTable
的测试数据。 (助手声明了它自己的继承自 Cucumber::Ast::DataTable
的子类。)这已被弃用,因此按照建议,我将继承替换为 Cucumber::MultilineArgument::DataTable
。
子类如下所示:
class ParsedTable < ::Cucumber::MultilineArgument::DataTable
def initialize(string)
super(string.split("\n").map do |line|
line = line.split('|').map(&:squish)
line.slice(1, line.length)
end)
end
end
然后有一堆测试助手可以像这样创建测试数据(假设 "role" 是我们要测试的模型):
def create_roles(string)
table = ParsedTable.new(string)
table.hashes.each do |hash|
create :role,
name: hash['Name'],
short_name: hash['Short Name'],
contracted_work_day: hash['Contracted workday in minutes']
end
end
这些助手是这样被调用的:
create_roles <<-eos
| Name | Contracted workday in minutes |
| Therapist | 390 |
eos
但是当那种电话打进来时,我得到 ArgumentError: data must be a Core::Ast::DataTable
。堆栈表示此异常来自 lib/cucumber/multiline_argument/data_table.rb:93:in 'initialize'
,这是 ParsedTable
定义中的 super
调用。
我一直在尝试围绕 Cucumber 来源追查此问题,但我无法弄清楚我做错了什么。
Cucumber 的 API 文档指出 Cucumber::MultilineArgument::DataTable 的构造函数采用 Core::Ast::DataTable
对象。
来源:https://www.rubydoc.info/gems/cucumber/Cucumber/MultilineArgument/DataTable#constructor_details
您将需要一个 Core::Ast::DataTable
的实例,而不是从字符串中自定义解析它。
Creates a new instance. +raw+ should be an Array of Array of String or an Array of Hash You don't typically create your own DataTable objects - Cucumber will do it internally and pass them to your Step Definitions.
来源:https://www.rubydoc.info/gems/cucumber-core/1.3.1/Cucumber/Core/Ast/DataTable#constructor_details
看起来 Cucumber 应该已经在步骤绑定中将 table 解析为 Core::Ast::DataTable
对象,因此您需要做的就是将其传递给 [= 的构造函数13=] class.
如果这不可用,则您需要提供一个字符串数组。
Greg Burghardt 的回答有其正确的理由; Cucumber::MultilineArgument::DataTable
class 需要一个 Core::Ast::DataTable
作为参数,而旧的 Cucumber::Ast::DataTable
则不是这样。 (这个 class 通常是 Cucumber 1.4.x 和当前版本之间的一个移动目标。)
最后我通过回避问题解决了这个问题。仔细查看使用自定义 ParsedTable
class 的方法,我发现它们并不真正依赖于 class,而是指望在每个实例上调用 hashes
。我需要的是对 hashes
做出适当回应的东西。
因此,我没有使用 subclassing Cucumber::MultilineArgument::DataTable
来获取自定义构造函数,而是用接受字符串的方法替换了 subclass 定义,将其拆分为行,并将 Array
行馈送到 Cucumber::MultilineArgument::DataTable#from
。这返回了一个 Cucumber::MultilineArgument::DataTable
的实例,我可以在其上调用 hashes
。那行得通。