首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >测试postgres最小的“随机()”

测试postgres最小的“随机()”
EN

Stack Overflow用户
提问于 2018-06-22 16:33:02
回答 1查看 290关注 0票数 2

引言

我在我的RoR项目中有一个层次结构的父-子项目,并且我为我们的rails项目编写了一个新的特性,它显示了来自父母的两个随机子记录。

代码语言:javascript
复制
class Article < ActiveRecord::Base
  has_many :reviews

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

代码语言:javascript
复制
class Review < ActiveRecord::Base
  belongs_to :article

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

现在,我遇到的问题是,即使随机性正确工作,即使在测试中,我也遇到了一些实际测试这个特性的测试的问题。

假设我有一个ArticlesControllerTest测试套件,它包含一个方法

代码语言:javascript
复制
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

问题

最后一个assert_equal失败了,例如:

  • response_article包含ids 1, 2
  • article.to_json包含ids 1, 3

问题

是否有可能编写某种过滤器,使postgres的RANDOM()始终返回常量值?我知道我可以使用SELECT setseed(0.5);设置种子,以便下一个SELECT RANDOM();返回相同的值(尽管下一个RANDOM()会改变),但是我想要实现的是在从活动记录中进行每一个可能的选择之前做一些类似setseed(0.5)的事情。

我很乐意采取任何其他的回应来帮助我解决这个问题,因为我知道RoR和Postgres是两个不同的服务器,我不知道如何从postgres这边测试这种随机性。

inb4:我不想以一种巨大的方式修改测试。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-06-22 16:44:33

您可能应该为此使用模拟/存根,确保仅在测试范围内就有一个一致的值。例如,使用摩卡咖啡

代码语言:javascript
复制
Article.any_instance.stubs(:to_json).returns({
  ...
  reviews: reviews.last(2).as_json,
  ...
})

代码语言:javascript
复制
Review.expects(:n_random).returns(Review.last(2))

而且,在本例中,您可以使用以下方法撤消这些操作:

代码语言:javascript
复制
Article.any_instance.unstub(:to_json)

注:我不确定类上的:n_random存根的语法,因为我没有环境来测试它,但希望您能够理解(来源在这里)。

这意味着,在您的测试中,您将看到一致的数据,覆盖RANDOM()顺序。这样,您就可以测试您的控制器,这是在执行预期的操作,而不必担心在测试env之外使用的随机数据。

要实现,只需在测试中包含上述内容之一,即

代码语言:javascript
复制
test 'show renders correct article' do
  Review.expects(:n_random).returns(Review.last(2))

  # 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
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50992195

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档