我的方法在控制台中打印已观看电视节目的列表。我想测试触发私有print_result
方法的调用方法:
def initialize(parser)
@parser = parser
@views_hash = parser.page_views
end
def call
puts "n"
puts 'LIST OF MOST POPULAR TV SHOWS'
print_results(sort_all)
puts "nn"
end
private
def print_results(sorted_hash)
puts "n"
puts "#{'TV Show'.center(20)} | VIEWS"
puts '---------------------+----------'
sorted_hash.each do |page, views_no|
puts "#{page.ljust(20)} | #{views_no}"
end
end
规格:
describe '#call' do
before do
double(print_results: expected_print)
subject.call
end
let(:expected_print) do
" TV Show | VIEWS
---------------------+----------
/that_70s_show | 1"
end
it 'print results' do
expect do
subject.views_hash.send(:print_results)
end.to output(expected_print).to_stdout
end
end
如何嘲笑这个print_results
,因为现在它向我展示了NoMethodError: undefined method
print_results`并同时返回打印的表格。
提取可测试方法;不要嘲笑标准输出
你要求做的似乎是一种反模式。除非你正在做一些非常不寻常的事情,否则你不应该测试规范中的核心Ruby函数,比如#put。即便如此,您也可能在当前规范中测试错误的东西。
相反,您应该验证sorted_hash是否包含预期值,或者格式化的输出字符串是否符合某些已知值。如果真的想要测试#print_results方法的输出,那么应该将其重构为一组更便于测试的方法。
在一个非常高的水平上,你应该做这样的事情:
def generate_results sorted_hash
results = []
sorted_hash.each do |page, views_no|
results.append "#{page.ljust(20)} | #{views_no}"
end
results
end
def formatted_output sorted_hash
str = <<~EOF
#{'TV Show'.center(20)} | VIEWS
---------------------+----------
EOF
str << generate_results(sorted_hash)
end
def print_results sorted_hash
puts formatted_output
end
这不是经过测试的代码,但它应该会给你一个大致的想法。这个概念是,每个方法都做一件简单的事情,在那里你可以检查返回值,以确保它是你所期望的,而不是试图模拟一个基本的东西,比如标准输出;只要工作"重构后的方法应该是可单独测试的,而新的#print_results只是将内容发送到标准输出,并不真正需要测试,除非您有monkeypatched Kernel#put或重新定义的标准输出。