2017-06-16 38 views
0

我有我的方法create如何用rspec测试一个方法是否在另一个方法内被调用?

module AnswerCreator 
    class Creator 
    def initialize(answer) 
     @answer = answer 
    end 

    def create 
     test_cases_results = run_test_cases 
     @answer.attempt = get_attempt_number 
     @answer.correct = correct?(test_cases_results) 

     ActiveRecord::Base.transaction do 
     @answer.save! 
     save_test_cases_results(test_cases_results) 
     Scorer::Changer.new(@answer).change 
     end 

     ComputeAnswerSimilarityJob.perform_later(@answer) 
    end 

    ... 

    end 
end 

和我有下面的测试吧:

it "creates the answer with the right attempt number, create the test case results and add the answer to be processed in background" do 
     answer_test_case_result_count = AnswerTestCaseResult.count 
     jobs_count = enqueued_jobs.size 

     user = create(:user) 
     team = create(:team) 
     question = create(:question) 
     create_pair(:test_case, question: question) 
     create(:answer, question: question, user: user, team: team) 
     answer = build(:answer, question: question, user: user, team: team) 

     # These answers must be ignored >> 
     create(:answer, question: question, user: user) 
     create(:answer, question: question, team: team) 
     create(:answer, user: user, team: team) 

     described_class.new(answer).create 

     expect(answer.new_record?).to be_falsey 
     expect(answer.attempt).to eq 2 
     expect(AnswerTestCaseResult.count).to eq answer_test_case_result_count + 2 
     expect(enqueued_jobs.size).to eq jobs_count + 1 
     end 

Creator与创建应答对象的时候,创建逻辑类交易。我的Changer类处理与Answer对象关联的评分逻辑。我不想在Creator里测试这个逻辑,但我想确保调用Changerchange方法。

我该如何测试?

回答

1

所以,你有这行代码要测试:

Scorer::Changer.new(@answer).change 

我最初的想法是建议allow_any_instance_of,但是当你在这个链接看到,RSpec的团队反对这一提议。如果你想,不过,你可以把这个测试案例中,调用Creator#create前:

expect_any_instance_of(Scorer::Changer).to receive(:change).and_call_original 

Withoug expect_any_instance_of,给我所知,你不得不存根构造函数:

fake_answer = "???" # change to the value of 'answer' in your test case 
fake_changer = Scorer::Changer.new fake_answer 
expect(Scorer::Changer).to receive(:new).and_return fake_changer 
expect(fake_changer).to receive(:change).and_call_original 

这种事情有点乏味,但是当函数在私有状态方面有很多事情发生时会发生什么。例如,如果您将Scorer::Changer.new电话转到Creator#initialize,该怎么办?

attr_reader :changer 
def initialize(answer) 
    @answer = answer 
    @changer = Scorer::Changer.new @answer 
end 

然后,你需要做的少一点磕碰:

fake_answer = "???" 
creator = AnswerCreator::Creator.new fake_answer 
expect(creator.changer).to receive(:change).and_call_original 
creator.create 
+0

所有选项工作得很好。非常感谢! – rwehresmann

相关问题