ruby-on-rails - 在 minitest 中测试 postgres“RANDOM()”
问题描述
介绍
我的 RoR 项目中有一个层次结构父子,我为我们的 ruby on rails 项目编写了一个新功能,它显示了来自父项的两个随机子记录。
class Article < ActiveRecord::Base
has_many :reviews
def to_json
{
...
reviews: reviews.n_random.as_json
...
}
end
end
和
class Review < ActiveRecord::Base
belongs_to :article
scope :n_random, ->(n=2) { order("RANDOM()").limit(n) }
end
现在,我遇到的问题是即使随机性正常工作,即使在测试中,我也遇到了一些实际间接测试此功能的测试的问题。
假设我有一个ArticlesControllerTest
测试套件,其中包含一个方法
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
包含 ID1, 2
article.to_json
包含 ID1, 3
问题
是否可以编写某种过滤器,使 postgres 的RANDOM()
返回值始终为常量?我知道我可以SELECT setseed(0.5);
用来设置种子,以便下一个SELECT RANDOM();
返回相同的值(尽管下一个RANDOM()
会改变),但我想要实现的是setseed(0.5)
在从活动记录中进行每个可能的选择之前做一些事情。
我很乐意接受任何其他可以帮助我解决这个问题的回复,因为我知道 RoR 和 Postgres 是两个不同的服务器,我不知道如何从 postgres 方面测试这种随机性。
inb4:我不想大幅度修改测试。
解决方案
您可能应该为此使用模拟/存根,以确保仅在此测试范围内具有一致的值。例如,使用Mocha:
Article.any_instance.stubs(:to_json).returns({
...
reviews: reviews.last(2).as_json,
...
})
或者
Review.expects(:n_random).returns(Review.last(2))
而且,在本例中,您可以使用以下方法撤销这些:
Article.any_instance.unstub(:to_json)
注意我不确定:n_random
类上存根的语法,因为我没有测试它的环境,但希望你能明白(来源在这里)。
这意味着,在您的测试中,您将看到一致的数据,覆盖RANDOM()
排序。这样您就可以测试您的控制器是否正在执行预期的操作,而不必担心在测试环境之外使用的随机数据。
要实施,只需在您的测试中包含上述之一,即
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
推荐阅读
- angular - 继承的类模板中的 WebStorm Angular 警告
- web-scraping - 如何使用 CrawlSpider 设置下一页规则?
- python - 使用 Numba 并行化矩阵计算
- bash - 将重定向传递给 bash 脚本
- javascript - 无效的属性 Bezier 设置 ... 到缺少插件?gsap.registerPlugin()
- python-3.x - Python 请求下载后文件损坏
- c++ - OpenCV 鱼眼校准 C++ 输出与 Python 不同
- python - 使用从一个 python 文件到另一个文件的全局变量
- python - 2 名玩家以 6 个标记开始。每轮掷出 3 个标准骰子。找到游戏的获胜者并估计玩家 2 获胜的概率
- powerbi - 创建一个返回多列 Power BI 的度量