ruby - 如何使用 rspec 测试 .each 迭代块内的标准输出?
问题描述
我有一个示例代码:
def print_stuff(first_num, second_num)
puts 'hello'
(first_num..second_num).to_a.each do |num|
puts 'The current number is: '
puts "#{num}"
end
end
我和使用 rspec,我想测试一下输出是否正确。我的尝试如下:
expect(initialize_program(1, 3)).to output(
"The current number is:
1
The current number is:
2
The current number is:
3").to_stdout
但是相反,我得到一个预期的块输出到标准输出,但不是块错误,因为 initialize_program(1,3) 正在输出文本,但它是在 .each 块内完成的,因此方法本身返回数字范围的数组.
如何测试块内的文本,以查看输出的文本是否正确?
谢谢!
解决方案
重构以检查字符串,而不是标准输出
这种类型的代码是您应该首先编写测试的原因。您实际上是在测试 Kernel#puts,它总是返回nil
,而不是验证您是否构建了您期望的字符串。不要那样做。相反,像这样重构:
def print_stuff(num1, num2)
str =
(num1..num2).map { |num|"The current number is: #{num}" }
.join "\n"
puts str
str
end
print_stuff 1, 3
#=> "The current number is: 1\nThe current number is: 2\nThe current number is: 3"
这不仅会在标准输出上打印您期望的内容:
The current number is: 1 The current number is: 2 The current number is: 3
但也会使用方法最后一行的隐式返回来返回一个值,您可以使用该值与规范中的期望进行比较。
您还可以重构该方法以返回一个字符串对象数组,或者您可能明确想要测试的任何其他内容。您的真实方法越能反映您计划测试的内容越好。
RSpec 示例
RSpec.describe '#print_stuff' do
it 'prints the expected message' do
expected_string = <<~EOF
The current number is: 1
The current number is: 2
The current number is: 3
EOF
expect(print_stuff 1, 3).to eql(expected_string.chomp)
end
# Even without the collection matchers removed in RSpec 3,
# you can still validate the number of items returned.
it 'returns the expected number of lines' do
lines = print_stuff(1, 3).split("\n").count
expect(lines).to eql(3)
end
end
在 IRB 中测试 RSpec 示例
在 irb 中,您可以像这样验证您的规格:
require 'rspec'
include RSpec::Matchers
expected_string = <<~EOF
The current number is: 1
The current number is: 2
The current number is: 3
EOF
# String#chomp is needed to strip the newline from the
# here-document
expect(print_stuff 1, 3).to eql(expected_string.chomp)
# test the returned object in other ways, if you want
lines = print_stuff(1, 3).split("\n").count
expect(lines).to eql(3)
推荐阅读
- python - 无法在 python 中获取产品 ID(Web 元素)
- sql - 单元格中的多行值
- ios - 将 SecAccessControl 与密码和生物识别一起使用时,钥匙串 SecItemAdd 失败
- charts - barsince 函数问题 - tradingview pine
- flutter - RadioListTile 不适用于 setstate
- cmake - CMake 工具链文件:有没有办法指定包含和定义的语法?
- angular - 如果没有匹配的子路由,角度路由应该会失败
- javascript - 如何使用 CSS 为与父 div 标签相关的嵌套 div 标签提供边距?
- amazon-web-services - AWS Cloud9:你能停止环境吗?
- omnet++ - 如何在静脉应用程序顶部添加路由功能?