gpt4 book ai didi

ruby-on-rails - 在共享示例调用中的 let 中使用循环变量

转载 作者:数据小太阳 更新时间:2023-10-29 08:43:48 27 4
gpt4 key购买 nike

我正在为使用 RoR & Prawn 生成的 PDF 编写规范。该 PDF 有一堆过滤器选项(其中 24 个)。为了不错过任何重要的规范,我在 before :context block 中生成过滤器选项,并将它们保存在实例变量中。

我的问题开始于尝试遍历所有过滤器选项并运行共享示例,以测试不会因不同过滤器而发生太大变化的基础知识。

这就是我的代码对于所有这些过滤器和文档过滤器的样子(filter_setting 方法只是访问特定 @major_filter_options 的帮助程序):

describe 'pdf' do
before :context do
@major_filter_options = {}
@major_filter_options.define_them
end

describe 'basic content' do
before :context do
@filter_options_with_docu = {}
# find all the filters that have the docu option enabled
@major_filter_options.each do |key, mfo|
@filter_options_with_docu[key] = mfo if key.to_s.include? 'docu'
end
end

24.times do |t| # can't access major_filter_options.size here.. it's nil.
include_examples 'first_3_pages' do
let(:pdf) do
filter_options = filter_setting(@major_filter_options.keys[t])
ProjectReport::ReportGenerator.new.generate(project, filter_options, user).render
end
let(:page_analysis) { PDF::Inspector::Page.analyze(pdf) }
end
end

12.times do |t| # @print_options_with_docu is also nil at this point
include_examples 'documentation_content' do
let(:pdf) do
filter_options = filter_setting(@filter_options_with_docu.keys[t])
ProjectReport::ReportGenerator.new.generate(project, filter_options, user).render
end
let(:page_analysis) { PDF::Inspector::Page.analyze(pdf) }
end
end
# ...
end

我有两个大问题:

其中一个是 24.times12.times 等等(有很多)困扰着我,因为它使维护变得更加困难。一个新的过滤器选项会改变所有的值,在我看来找到所有的值来改变它们很容易出错。

另一个问题是变量在这里迭代是这样的:12.times do |t| 当我在任何这些 let 中时,实际上似乎没有迭代:

let(:pdf) do
filter_options = filter_setting(@major_filter_options.keys[t])
puts t
# ...
end

这里的puts t每次都会打印11(filter每次也是一样的)。阅读后我发现 a gist example .这个问题看起来很相似,但遗憾的是在它周围放置一个 describe block 并没有太大作用。

24.times do |t|
describe
# same as before
end
end

不过有趣的是,当在该设置中再次执行 puts 时,每次都是 6,这让我有点困惑。

我还应该提一下,之所以将它们分开,是因为我分享了仅适用于某些过滤器的示例。如果有人对如何做有更好的想法,例如迭代 @major_filter_options 然后根据当前哈希 key 调用某些共享示例,我洗耳恭听!

最佳答案

关于您无法对您在 before :context block 中定义的实例变量调用 .times:

RSpec 分两个阶段工作。在第一阶段,它执行规范文件中的 Ruby 代码; letbefore 以及 it 方法存储它们的 block 以便稍后运行。在第二阶段,它实际运行测试,即 letbeforeit block 的内容。 before :context block 直到第二阶段才定义 thost 实例变量,因此在第一阶段运行的 .times 语句看不到实例变量。

解决方案是将过滤器选项放在 RSpec 到达 .times 语句之前初始化的某个位置,就像一个常量。

关于在循环中始终使用循环变量的相同值的 include_examples:

include_examples 在当前上下文中包含给定的共享示例。如果多次包含相同的示例,示例本身将被包含多次,但最后一次包含的 let 将覆盖所有先前包含的 letThe RSpec documentation has a clear example.

解决方案是使用 it_behaves_like 而不是 include_examplesit_behaves_like 将包含的示例放入嵌套示例组中,因此 let 不能相互覆盖。

应用这两个解决方案会得到如下结果:

describe 'pdf' do
describe 'basic content' do
MAJOR_FILTER_OPTIONS = # code that initializes them
MAJOR_FILTER_OPTIONS.values.each do |filter_option|
it_behaves_like 'first_3_pages' do
let(:pdf) do
filter_options = filter_setting(filter_option)
ProjectReport::ReportGenerator.new.generate(project, filter_options, user).render
end
let(:page_analysis) { PDF::Inspector::Page.analyze(pdf) }
end
end

FILTER_OPTIONS_WITH_DOCU = # code that chooses them from MAJOR_FILTER_OPTIONS
FILTER_OPTIONS_WITH_DOCU.values.each do |filter_option|
it_behaves_like 'documentation_content' do
let(:pdf) do
filter_options = filter_setting(filter_option)
ProjectReport::ReportGenerator.new.generate(project, filter_options, user).render
end
let(:page_analysis) { PDF::Inspector::Page.analyze(pdf) }
end
end

end
end

关于ruby-on-rails - 在共享示例调用中的 let 中使用循环变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38869067/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com