Rswag and FactoryBot - how to make them play nicely?

60 Views Asked by At

I am trying to write an Rswag test for some ActiveRecord validation against the account of a newly created record.

The issue I am having is that I can't work out how to create an Account using FactoryBot and then have it still exist when the test runs. Since the model validation uses the database layer to fetch the record, it needs to still be within the context in which FactoryBot created the record.

I can't define the model outside the test, and I can't modify the parameter inside the test.

One thing that would solve this is if there was a way to modify a parameter from inside the test without using let. But I can't find anything about that in the documentation.

Has anyone else had this issue and found a solution? I feel like I can't be the only one trying to write tests in this way.

I have tried this way (simplified code):

parameter name: :account_id, in: :query, type: :integer

response(422, 'account not permitted') do
    account = FactoryBot.create(:account, forbidden: true)
    let(:account_id) { account.id }

    run_test!
end

This correctly sets the parameter to the ID of the newly created Account, but then when the validation code runs in the model class, the Account does not exist as far as ActiveRecord is concerned, I assume because it wasn't created 'inside' the test.

I've also tried this way:

parameter name: :account_id, in: :query, type: :integer

response(422, 'account not permitted') do
    before do
      account = FactoryBot.create(:account, forbidden: true)
      let(:account_id) { account.id }
    end

    run_test!
end

This way fails because you can't call let from inside the before block. Not sure exactly why this is prevented but I'm sure there's a good reason for it.

1

There are 1 best solutions below

0
On

Of course, as soon as I posted this I suddenly realized the solution. Put the FactoryBot call inside the let block.

response(422, 'account not permitted') do
    let(:account_id) do 
      account = FactoryBot.create(:account, forbidden: true)
      account.id
    end

    run_test!
end