7

I can't seem to get this test to pass and I don't understand why.

controller_spec.rb:

require 'rails_helper'

RSpec.describe QuotationRequestsController, type: :controller do

  describe "GET download" do    
    it "streams the sample text as a text file" do
      #setup
      quotation_request = create(:quotation_request)
      file_options = {filename: "#{quotation_request.id}-#{quotation_request.client.name.parameterize}.txt", type: 'plain/text', disposition: 'attachment'}

      #exercise
      get :download, id: quotation_request

      #verification
      expect(@controller).to receive(:send_data).with(file_options) {@controller.render nothing: true}      
    end
  end
end

controller:

def download
  @quotation_request = QuotationRequest.find(params[:id])
  send_data @quotation_request.sample_text, {
    filename: @quotation_request.sample_text_file, 
    type: "text/plain",
    disposition: "attachment"
  }
end

Output of test:

1) QuotationRequestsController GET download streams the sample text as a text file
  Failure/Error: expect(@controller).to receive(:send_data).with(file_options) {
    @controller.render nothing: true
  }       
  (# <QuotationRequestsController:0x007ff35f926058>).send_data({
    :filename=>"1-peter-johnson.txt",
    :type=>"plain/text",
    :disposition=>"attachment"
  })  
  expected: 1 time with arguments: ({
    :filename=>"1-peter-johnson.txt",
    :type=>"plain/text", :disposition=>"attachment"
  })
  received: 0 times
  # ./spec/controllers/quotation_requests_controller_spec.rb:380:in `block (3 levels) in <top (required)>'
  # -e:1:in `<main>'
dinjas
  • 2,115
  • 18
  • 23
chell
  • 7,646
  • 16
  • 74
  • 140

4 Answers4

4

You should pass 2 arguments expect(@controller).to receive(:send_data).with(quotation_request.sample_text, file_options) {@controller.render nothing: true}

Elena Unanyan
  • 1,149
  • 9
  • 14
3
  #exercise
  get :download, id: quotation_request

  #verification
  expect(@controller).to receive(:send_data).with(file_options) {@controller.render nothing: true}      

This is backwards. The expectation should come before the method call.

zetetic
  • 47,184
  • 10
  • 111
  • 119
  • 1
    I reversed the above two lines and I'm still getting the same error. Any ideas ? How should I write this test? – chell Sep 19 '16 at 02:38
  • This should be the solution, unless your controller action is not completing successfully. – fylooi Sep 25 '16 at 11:29
  • The controller action is completing successfully as I can test it in the browser. – chell Sep 27 '16 at 02:05
1

You write following:

  1. Get file
  2. Mock file

But right case is inverted:

  1. Mock file
  2. Get file

try following (using before):

require 'rails_helper'

RSpec.describe QuotationRequestsController, type: :controller do
  describe "GET download" do   
    let(:quotation_request) { create(:quotation_request) }
    let(:file_options) { {filename: "#{quotation_request.id}-#{quotation_request.client.name.parameterize}.txt", type: 'plain/text', disposition: 'attachment'} }

    before do
      expect(@controller).to receive(:send_data)
         .with(file_options) { @controller.render nothing: true }
    end

    it "streams the sample text as a text file" do
      get :download, id: quotation_request
    end
  end
end
itsnikolay
  • 17,415
  • 4
  • 65
  • 64
1

Rails 5:

expect(@controller).to receive(:send_data).with(quotation_request.sample_text, file_options) {@controller.head :ok}

Ref: https://stackoverflow.com/a/43428992

rAzOr
  • 300
  • 6
  • 19