vendredi 22 juin 2018

Testing postgres "RANDOM()" in minitest

Introduction

I have a hierarchy parent-children in my RoR project and I wrote a new feature to our ruby on rails project, that shows two random children records from a parent.

class Article < ActiveRecord::Base
  has_many :reviews

  def to_json
    {
      ...
      reviews: reviews.n_random.as_json
      ...
    }
  end
end

and

class Review < ActiveRecord::Base
  belongs_to :article

  scope :n_random, ->(n=2) { order("RANDOM()").limit(n) }
end

Now, the problem that I have is even though the randomness works correctly, even in tests, I have problems with few tests that actually test this feature indirectly.

Let's say that I have an ArticlesControllerTest test suite, that contains a method

test 'show renders correct article' do
    # given
  params = { format: :json, id: 1 } 
  article = Article.find(params[:id])

    # when
  post :get, params
  response_article = JSON.parse(response.body, symbolize_names: true)


    #then
  assert_response 200
  assert_equal response_article, article.to_json
end

Problem

The last assert_equal fails, because for example:

  • response_article contains ids 1, 2
  • article.to_json contains ids 1, 3

Question

Is it possible to write some kind of a filter, that makes postgres's RANDOM() return always constant value? I know that I can use SELECT setseed(0.5); to set seed, so that next SELECT RANDOM(); returns the same value (although the next RANDOM() will change), but what I would like to achieve is to do something like setseed(0.5) before every possible select from active records.

I'll gladly take any other responses that will help me with this problem, because I know that RoR and Postgres are two different servers and I have no idea how to test this randomness from postgres's side.

inb4: I don't want to modify tests in a huge way.




Aucun commentaire:

Enregistrer un commentaire