【问题标题】:Test failing - one class method to call another ("expected: 1 time with arguments, received 0 times")测试失败 - 一个类方法调用另一个(“预期:1 次带参数,收到 0 次”)
【发布时间】:2017-07-15 08:37:32
【问题描述】:

我的问题:

我正在尝试对返回该类的实例的类方法进行存根,但在题为“使用 CSV 数据创建实例”的测试中出现以下错误:

Failures:

  1) QuestionData.load_questions creates an instance with CSV data
     Failure/Error: expect(question_data_class).to receive(:new).with(data).and_return(question_data_instance)

       (QuestionData (class)).new([{:time_limit=>10, :text=>"Who was the legendary Benedictine monk who invented champagne?", :correct_...the world?", :correct_answer=>"Lake Superior", :option_2=>"Lake Victoria", :option_3=>"Lake Huron"}])
           expected: 1 time with arguments: ([{:time_limit=>10, :text=>"Who was the legendary Benedictine monk who invented champagne?", :correct_...the world?", :correct_answer=>"Lake Superior", :option_2=>"Lake Victoria", :option_3=>"Lake Huron"}])
           received: 0 times

上下文:

代码(如下所示)有效 - QuestionData.load_questions 从 CSV 文件加载数据并以数据作为参数调用 QuestionData.new。然而,我对.load_questions 方法的测试给出了上述错误。当它被调用时,QuestionData 类的双精度没有收到带有 data 双精度的 .new 的存根。

我尝试研究如何测试返回另一个存根或实例的存根,但似乎找不到相关答案。

非常感谢任何帮助或建议,在此先感谢!

代码:

require "csv"

class QuestionData

  attr_reader :questions

  def initialize(questions)
    @questions = questions
  end

  def self.load_questions(file = './app/lib/question_list.csv', questions = [])
    self.parse_csv(file, questions)
    self.new(questions)
  end

  def self.parse_csv(file, questions)
    CSV.foreach(file) do |row|
      time_limit, text, correct_answer, option_2, option_3 = row[0],
       row[1], row[2], row[3], row[4]
      questions << { time_limit: time_limit, text: text,
        correct_answer: correct_answer, option_2: option_2, option_3: option_3
      }
    end
  end

end

测试文件:

require './app/models/question_data'

describe QuestionData do

  subject(:question_data_instance) { described_class.new(data) }
  let(:question_data_class) { described_class }
  let(:CSV) { double(:CSV, foreach: nil) }
  let(:questions) { [] }
  let(:file) { double(:file) }
  let(:data) do
    [{
      time_limit: 10,
      text: "Who was the legendary Benedictine monk who invented champagne?",
      correct_answer: "Dom Perignon",
      option_2: "Ansgar",
      option_3: "Willibrord"
      },
      {
        time_limit: 12,
        text: "Name the largest freshwater lake in the world?",
        correct_answer: "Lake Superior",
        option_2: "Lake Victoria",
        option_3: "Lake Huron"
      }]
  end

  describe '#questions' do
    it "has an array of question data from CSV" do
      expect(question_data_instance.questions).to eq(data)
    end
  end

  describe '.parse_csv' do
    it "parses CSV data into hash data" do
      expect(CSV).to receive(:foreach).with(file)
      question_data_class.parse_csv(file, questions)
    end
  end

  describe '.load_questions' do
    it "calls '.parse_csv' method" do
      expect(question_data_class).to receive(:parse_csv).with(file, questions)
      question_data_class.load_questions(file, questions)
    end

    it "creates an instance with CSV data" do
      allow(question_data_class).to receive(:load_questions).with(file, questions).and_return(question_data_instance)
      allow(question_data_class).to receive(:new).with(data).and_return(question_data_instance)
      expect(question_data_class).to receive(:new).with(data).and_return(question_data_instance)
      question_data_class.load_questions(file, questions)
    end
  end

  describe '.new' do
    it "creates a new instance with CSV data" do
      expect(question_data_class).to receive(:new).with(data).and_return(question_data_instance)
      question_data_class.new(data)
    end
  end

end

【问题讨论】:

    标签: ruby rspec stub stubbing stubs


    【解决方案1】:

    问题是你正在打断电话:

    allow(question_data_class).to receive(:load_questions).with(file)
    

    如果您仍然希望调用执行,您需要添加:

    and_call_original
    

    因此原始方法将被执行,您的代码将在原始块上调用新方法。

    但问题是你不需要存根类你只需要更改存根因为你在一个双精度上调用该方法,它会尝试在一个类中执行它,所以你可能需要将您的第二个测试更改为:

    describe '.load_questions' do
      it "creates an instance containing CSV data" do
        expect(described_class).to receive(:new).with(data).and_return(question_data_instance)
        described_class.load_questions(file)
      end
    end
    

    【讨论】:

    • 嗨 aledustet,非常感谢您回答我的问题,我很抱歉,我只是意识到我最初发布的代码在询问之前无法正常工作。我现在对它进行了如此轻微的更改,现在它 100% 可以工作(但我仍然不知道如何测试它并为我的测试得到相同的错误)。再次深表歉意,非常感谢您抽出宝贵时间。我已尝试将您的 described_class 想法纳入我的新测试,但目前还没有运气(再次感谢您的提示!)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多