Search code examples
ruby-on-railsrspecfog

Rspec, Paperclip and Rails - spec with fixture_file_upload works as single, not in group


I have a spec that passes when run on its own but, when I run it as part of either a directory of tests or my entire suite, it fails.

Spec:

WebMock.disable!

describe MembersUpload::ParseSpreadsheet do

  let(:client) { create(:client) }
  let(:members_upload) { create(:members_upload, client: client) }

  context 'parsing an uploaded spreadsheet' do
    it 'should parse the spreadsheet and add rows' do
      MembersUpload::ParseSpreadsheet.call(client.id, members_upload.id)
      members_upload.reload
      expect(members_upload.spreadsheet_rows).to be > 0
    end
  end

end

Factory:

FactoryGirl.define do  

  factory :members_upload do
    association :client
    ignore_duplicates false
    send_welcome_letters false
    spreadsheet_rows 0
    total_added 0
    invalid_percent 0
    disallowed_percent 0
    unknown_percent 0
    accept_all_percent 0
    invalid_violation false
    disallowed_violation false
    status 'scheduled'
    approved false
    approve_by Date.today + 14.days
    approval_type 'client'
    spreadsheet { fixture_file_upload "#{Rails.root}/spec/fixtures/member_uploads/members-uploads-samples-good.csv", 'text/csv' }
  end
end

When run as part of a suite or group of tests, I get the following error:
NoMethodError: undefined method body for nil:NilClass

The error itself points to a fog method called copy_to_local_file and would seem to indicate that it could not load the file/file's contents.

I feel as though I must be missing something obvious as to why this test would pass on its own but not as part of a suite/group.

I'm new to Rspec as it relates to/handles uploaded files and am stumped as to where to start (I have googled this but found little).


Solution

  • I think the copy_to_local_file you mention is when paperclip tries to use for to talk to S3. Which is fine in a production setting, but probably not what you want in testing.

    If you add Fog.mock = true to your test setup, it will create a mocked version of S3 locally which can be operated against. Then you can save a copy of the associated model (which will instantiate this "file" in memory) in your test setup and it should then subsequently be something you can read back out.

    Hope that helps!