A
A
Anton Misyagin2020-02-06 13:04:34
ruby
Anton Misyagin, 2020-02-06 13:04:34

How to write an rspec test to test a controller for race conditions?

Good afternoon everyone, I ask for help. How do I write a test for a RoR application in which I want to test for the absence of race conditions in a controller action. Read the article Testing race conditions in your Rails app by Robert Pankowecki. It literally came out like this:

describe Cabinet::Balance::BalanceController do
        render_views
        controller_methods = [{name: :prolongation, method: 'POST', params: {}}]
        describe 'prolongation action' do
                it 'ловим двойное списание средств' do
                        active_adv = FactoryBot.create :active_adv
                        active_adv.touch :expired_at
                        active_adv.save

                        user = active_adv.user
                        user.amount = PriceList.prolongation.price
                        user.save
                        # Логинимся, продлеваем объявление
                        login_user user


                        threads = 2.times.map do |i|
                                Thread.new do
                                        request.env["HTTP_ACCEPT"] = 'application/json'
                                        post :prolongation, :params => {id: active_adv.id}
                                        expect(response).to have_http_status :ok
                                end
                        end
                    threads.each(&:join)
                end
        end
end

The problem started the moment I started sending post requests in the thread body. I started getting all sorts of errors. Now I remember one saying that I call the render function twice, the second: Circular dependency detected while autoloading constant DeviseController.
Then I found on the forums that debugging controllers in this way is not allowed and that you need to remove the logic from the controller and test not the controller. Is it true? I do not want to shift the logic from the controller to other places. Has anyone done these tests? Happened? How did you do it?

PS The answer of the same Robert Pankowecki in the stackoverflow comments to a similar question:
The blog post was written for testing models/service objects. I am not sure if controllers tests are thread-safe in Rails. If there are many requests which request/response do you expect to be testing? It might be easier for you to test this logic if you extract non-http related concerns to a service and test that without doing HTTP requests
. – Robert Pankowecki

Answer the question

In order to leave comments, you need to log in

1 answer(s)
K
kaasmith, 2020-02-20
@kaasmith

In the article, he tests the race condition on the example of database access.
This line is very important, it is just about the pool of connections to the database.

expect(ActiveRecord::Base.connection.pool.size).to eq(5)

In the controller, I would not test this logic, you should not have a bottle neck there. But it might be in the database. Make a service object or transfer logic to a model and test there.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question