如何在Rails应用程序(Rspec)中测试ElasticSearch

我想知道您在使用ElasticSearch和Tire时如何在应用程序中测试搜索。

  • 如何设置新的ElasticSearch测试实例? 有没有办法模拟它?

  • 您知道的任何宝石都可以帮助您吗?


我发现一些有用的东西:

我找到了一篇很棒的文章,几乎回答了我所有的问题:)

[HTTP://bits and bit.饿死/post/11295134047/unit-testing-with-tire-安定-elastic-search#第三曲是_thread]

另外,Tire作者Karmi还提供了答案。

这也很有用:[https://github.com/karmi/tire/wiki/Integration-Testing-Rails-Models-with-Tire]

我不敢相信我在问之前没有找到这些...

3个解决方案
34 votes

为当前环境添加索引名称前缀

您可以为每个环境(在您的情况下:测试环境)设置一个不同的索引名。

例如,您可以在以下位置创建一个初始化程序

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)上进行测试。然后在您的environment / test.rb中进行设置

Tire::Configuration.url "http://localhost:1234"

然后在合适的位置(例如,测试启动),可以使用以下命令删除ElasticSearch测试实例上的所有索引:

Tire::Configuration.client.delete(Tire::Configuration.url)

也许您仍然必须确保您的模型类的Tyre-Mapping定义仍在被调用。

spaudanjo answered 2020-07-29T23:38:41Z
11 votes

在我的rspec套件中通过轮胎删除我的Elasticsearch索引时,我遇到了一个古怪的错误。 在我的Rspec配置中,类似于Bits and 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

媒体是我的榜样。

mhamrah answered 2020-07-29T23:39:15Z
4 votes

我遇到了类似的问题,这是我如何解决的。 切记,我的解决方案基于@spaudanjo解决方案。 由于我使用的是spork,因此我将其添加到YOURRAILSNAMEHERErails console块中,但是您可以将其添加到任何其他/ before块中。

# 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也不会刷新索引(即使在运行YOURRAILSNAMEHERE之后),这就是为什么存在随机前缀的原因。

它还会加载每个模型并检查它是否响应YOURRAILSNAMEHERE,这样我们就不再需要在rails console和其他区域中维护所有对轮胎响应的模型的列表。

由于此方法在使用后不会“删除”索引,因此您必须定期手动删除它。 虽然我不认为这是个大问题,但是您可以使用以下命令删除它:

YOURRAILSNAMEHERE

要查找YOURRAILSNAMEHERE是什么,请运行rails console,然后运行Rails.application.class.parent_name.downcase。输出将是项目的名称。

Hengjie answered 2020-07-29T23:39:54Z
translate from https://stackoverflow.com:/questions/9676089/how-to-test-elasticsearch-in-a-rails-application-rspec