[英]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.