如何在 rails 控制器中存根自我方法

How to stub self methods in rails controller

我有一个带有以下代码的控制器。

def apply
  file_id = params[:file_id]

  if file_id.nil? && params[:file].nil?
    render json: '"No resume was provided"', status: :unprocessable_entity
    return
  end

  if params[:job_id].nil?
    render json: '"Invalid data was posted"', status: :unprocessable_entity
    return
  end

  job = Job.find(params[:job_id]) if Job.exists?(params[:job_id])
  if job.nil?
    render json: '"Unable to locate job for application"', status: :unprocessable_entity
    return
  end

  if file_id.nil? || file_id.to_i == 0
    resume = ApiController.save_file job.owner
  else
    resume = UploadedFile.find(file_id)
  end

  resume.person = ApiController.save_person(job.owner)
  resume.save_by(job.owner)

  render json: '"successfully saved application"', status: 200
end

def self.save_file(owner)
  resume = UploadedFile.new
  resume.attachment = params[:file]
  resume.owner = owner
  unless resume.save_by(User.system)
    render json: '"There was an error uploading this file, please make sure the file type is an accepted file type."', status: :unprocessable_entity
    return
  end
  return resume
end

def self.save_person(owner)
  person = Person.new(apply_params.permit(:first_name, :last_name, :zip))
  ...

  result = person.save_by(owner)

  unless result
    render json: '"Errors occurred while saving person."', status: :unprocessable_entity
    return
  end

  return person
end

我正在尝试单独测试所有 3 个方法,但由于 apply 方法调用 save_file 和 save_person 方法,我想我需要在测试 apply 方法时对它们进行存根,对吗?所以,这让我想到了这段代码......

  describe 'apply' do

    before(:each) do
      @file = Rack::Test::UploadedFile.new(Rails.root.join('spec/fixtures/files/test-resume.txt'), 'plain/text')
      @fake_uploaded_file = UploadedFile.new
      @fake_job = Job.new
      @fake_job.id = 1
      @fake_person = Person.new
      allow(Job).to receive(:find).and_return(@fake_job)
      allow(Job).to receive(:exists?).and_return(true)
      allow(UploadedFile).to receive(:find).and_return(@fake_uploaded_file)
      allow(controller).to receive(:save_file).and_return(@fake_uploaded_file)
      allow(controller).to receive(:save_person).and_return(@fake_person)
    end

    it 'accepts an uploaded file and saves it' do
      post :apply, file: @file, job_id:1, format: :json
      expect(controller).to receive(:save_file)
    end
  end

当我尝试 运行 此测试时,我收到一条错误消息,指出 ApiController 未实现:save_file 我如何正确测试此应用方法以存根 save_file和 save_person 方法?谢谢

save_file 和 save_person 方法是 class 方法。所以他们应该像这样存根。

allow(ApiController).to receive(:save_file).and_return(@fake_uploaded_file)
allow(ApiController).to receive(:save_person).and_return(@fake_person)