【问题标题】:How to write rspec with mocking如何使用模拟编写 rspec
【发布时间】:2021-06-25 07:09:09
【问题描述】:

我想通过模拟这个方法来编写一个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 detected\n")
#checker is instance of CheckError class
  puts "#{@check.checker.file_path} :: No offensenses detected\n"
      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 并检查执行块。

【问题讨论】:

    标签: ruby rspec


    【解决方案1】:

    由于这一行,在您当前的实现中模拟 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 detected\n")
    end
    

    【讨论】:

    • 关于“我应该打破这种方法吗?”的问题,如果没有更多上下文,这很难说。 check_result 实际上应该实现什么?它只是记录错误而不是直接返回有用的结果(例如true/false),这有点奇怪,而且您将每个结果记录两次也很奇怪:一次到文件,然后再次到标准输出。
    • @NSRAghuwansi 足够公平(尽管 IMO 这是一个愚蠢的要求,但无论如何)。即便如此,我可能会选择传递一系列日志输出——比如check_result(logs: [$stdout, File.new('result.txt', 'a+')])。但无论如何,这不是一个非常复杂的方法,所以不是一个大问题。
    • @NSRAghuwansi “条件真假” -- 我不明白你的问题。至于该主题的外部资源,关于该主题的文章、示例和视频数不胜数;你有能力查找它们。我没有具体的推荐。
    • @NSRAghuwansi 如果没有minimal reproducible example,很难给出具体建议;你从来没有展示过@errors 到底是什么,或者这个check_result 方法定义在哪个类中。我的意思是,你可以 使用instance_variable_set('@errors') 模拟该值,但几乎可以肯定有更好的方法。比如,你能不能只在一个预期会返回错误的上下文中运行此方法,而在另一个预期不会返回错误的上下文中运行此方法?
    • @NSRAghuwansi 它仍然不是真正的minimal reproducible example,因为您还没有展示Operations 类是如何使用的。事实上,我认为目前该类没有意义,因为您没有使用path 对其进行初始化并将@path 实例变量设置为任何值。
    猜你喜欢
    • 1970-01-01
    • 2019-11-07
    • 1970-01-01
    • 2015-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-04
    • 2014-02-04
    相关资源
    最近更新 更多