我想通过模拟这个方法来编写一个rspec
测试。我应该打破这种方法,因为它做了很多事情吗?
require 'yaml'
require_relative 'checkerror'
class Operations
def initialize
@check
end
def result (result_log: File.new('result.txt', 'a+'))
if @check.errors.empty?
result_log.write("#{@check.checker.file_path} :: No offensenses detectedn")
#checker is instance of CheckError class
puts "#{@check.checker.file_path} :: No offensenses detectedn"
else
@check.errors.uniq.each do |err| puts "#{@check.checker.file_path} : #{err}n"
result_log.write("#{@check.checker.file_path} : #{err}n")
end
end
result_log.close
end
end
end
如果@check.errors需要使用一个值进行stuubed并检查执行块。
在当前实现中嘲笑f
对象会很尴尬,因为这一行:
f = File.new('result.txt', 'a+')
你需要在rspec
测试中写一些奇怪的东西,比如:
allow(File).to receive(:new).with('result.txt', 'a+').and_return(mock_file)
因此,我建议使用依赖项注入将文件传递到方法中。例如:
def check_result(results_log: File.new('result.txt', 'a+'))
if @errors.empty?
# ...
end
现在,你的rspec
测试可以看起来像这样:
let(:results_log) { Tempfile.new }
it "prints errors to log file" do
wharever_this_object_is_called.check_result(result_log: results_log)
expect(result_log.read).to eq("checker_file_path.txt :: No offences detectedn")
end