简体   繁体   English

测试失败 - 一个类方法调用另一个(“预期:1次带参数,收到0次”)

[英]Test failing - one class method to call another (“expected: 1 time with arguments, received 0 times”)

My problem: 我的问题:

I'm trying to stub a class method that returns an instance of that class, but I'm getting the following error for the test entitled "creates an instance with CSV data": 我正在尝试存根返回该类实例的类方法,但是我为名为“使用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

The context: 上下文:

The code (shown below) works - QuestionData.load_questions loads data from a CSV file and calls QuestionData.new with the data as an argument. 代码(如下所示)有效 - QuestionData.load_questions从CSV文件加载数据,并以数据作为参数调用QuestionData.new My test for the .load_questions method however, is giving the above error. 然而,我对.load_questions方法的测试给出了上述错误。 When it's called, the double of the QuestionData class isn't receiving the stub of .new with the data double. 当它被调用时, QuestionData类的double没有接收带有data double的.new存根。

I've tried researching how to test stubs that return another stub or an instance, but can't seem to find a relevant answer. 我已经尝试过研究如何测试返回另一个存根或实例的存根,但似乎找不到相关的答案。

I'd really appreciate any help or advice, thanks very much in advance! 我非常感谢任何帮助或建议,非常感谢!

The code: 编码:

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

The test file: 测试文件:

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

The thing is that you are stubbing the call on: 问题是你正在打电话:

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

If you still want that the call executes you need to add a: 如果您仍然希望执行调用,则需要添加:

and_call_original

Therefore the original method will be executed and your code will call the new method on the original block. 因此,将执行原始方法,并且您的代码将在原始块上调用新方法。

But the thing is that you don't need to stub the class you just need to change the stubs because you are calling the method on a double, and it will try to execute it in a class, so you might need to change your second test to: 但问题是你不需要存储你只需要更改存根的类,因为你在double上调用方法,它会尝试在类中执行它,所以你可能需要更改你的第二个测试:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM