[英]How to test ElasticSearch in a Rails application (Rspec)
我想知道在使用ElasticSearch和Tire时如何在应用程序中测试搜索。
您如何设置新的ElasticSearch测试实例? 有没有办法嘲笑它?
你知道的任何宝石可能对此有所帮助吗?
我发现一些有用的东西:
我发现了一篇很棒的文章回答了我所有的问题:)
http://bitsandbit.es/post/11295134047/unit-testing-with-tire-and-elastic-search#disqus_thread
此外,还有来自轮胎作者卡米的答案。
这也很有用: https : //github.com/karmi/tire/wiki/Integration-Testing-Rails-Models-with-Tire
在问之前我无法相信我没有找到这些......
您可以为每个环境设置不同的索引名称(在您的情况下:测试环境)。
例如,您可以在中创建初始化程序
config/initializers/tire.rb
使用以下行:
Tire::Model::Search.index_prefix "#{Rails.application.class.parent_name.downcase}_#{Rails.env.to_s.downcase}"
假设您有名为Customer,Order和Product的模型,请将以下代码放在test-startup / before-block / each-run-block的某处。
# iterate over the model types
# there are also ways to fetch all model classes of the rails app automaticly, e.g.:
# http://stackoverflow.com/questions/516579/is-there-a-way-to-get-a-collection-of-all-the-models-in-your-rails-app
[Customer, Order, Product].each do |klass|
# make sure that the current model is using tire
if klass.respond_to? :tire
# delete the index for the current model
klass.tire.index.delete
# the mapping definition must get executed again. for that, we reload the model class.
load File.expand_path("../../app/models/#{klass.name.downcase}.rb", __FILE__)
end
end
另一种方法是设置一个不同的ElasticSearch实例来测试另一个端口,比方说1234.在你的enviornment / test.rb中,你可以设置
Tire::Configuration.url "http://localhost:1234"
在适当的位置(例如您的测试启动),您可以删除ElasticSearch测试实例上的所有索引:
Tire::Configuration.client.delete(Tire::Configuration.url)
也许您仍然必须确保您的模型类的轮胎映射定义仍然被调用。
在我的rspec套件中通过轮胎删除我的弹性搜索索引时遇到了一个奇怪的错误。 在我的Rspec配置中,类似于Bits和Bytes博客,我有一个after_each调用,它清理数据库并清除索引。
我发现我需要调用Tire的create_elasticsearch_index方法,该方法负责读取ActiveRecord类中的映射以设置适当的分析器等。我看到的问题是我在我的模型中有一些:not_analyzed字段实际上正在分析(这打破了我想要分面工作的方式)。
开发方面的一切都很好,但测试套件失败了,因为各个单词而不是整个多字符串都破坏了方面。 删除索引后,似乎没有在rspec中正确创建映射配置。 添加create_elasticsearch_index调用修复了问题:
config.after(:each) do
DatabaseCleaner.clean
Media.tire.index.delete
Media.tire.create_elasticsearch_index
end
媒体是我的模特课。
我遇到了类似的问题,这就是我解决它的方法。 请记住,我的解决方案建立在@spaudanjo解决方案之上。 由于我正在使用spork,我在spec_helper.rb
的Spork.each_run
块中添加了这个,但是你可以将它添加到任何其他每个/之前的块中。
# Define random prefix to prevent indexes from clashing
Tire::Model::Search.index_prefix "#{Rails.application.class.parent_name.downcase}_#{Rails.env.to_s.downcase}_#{rand(1000000)}"
# In order to know what all of the models are, we need to load all of them
Dir["#{Rails.root}/app/models/**/*.rb"].each do |model|
load model
end
# Refresh Elastic Search indexes
# NOTE: relies on all app/models/**/*.rb to be loaded
models = ActiveRecord::Base.subclasses.collect { |type| type.name }.sort
models.each do |klass|
# make sure that the current model is using tire
if klass.respond_to? :tire
# delete the index for the current model
klass.tire.index.delete
# the mapping definition must get executed again. for that, we reload the model class.
load File.expand_path("../../app/models/#{klass.name.downcase}.rb", __FILE__)
end
end
它基本上为每个测试用例定义了它自己的唯一前缀,因此索引中没有。 其他解决方案都遇到了一个问题,即使在删除索引之后,Elastic Search也不会刷新索引(即使在运行Model.index.refresh
),这就是随机化前缀存在的原因。
它还会加载每个模型并检查它是否响应tire
以便我们不再需要维护在spec_helper.rb
和其他区域中响应轮胎的所有模型的列表。
由于此方法在使用后不会“删除”索引,因此您必须定期手动删除它。 虽然我不认为这是一个很大的问题,但您可以使用以下命令删除:
curl -XDELETE 'http://localhost:9200/YOURRAILSNAMEHERE_test_*/'
要查找YOURRAILSNAMEHERE
是什么,请运行rails console
并运行Rails.application.class.parent_name.downcase
。 输出将是您项目的名称。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.