如何在Rails应用程序中testingElasticSearch(Rspec)

我想知道如何在使用ElasticSearch和Tire时在应用程序中testingsearch。

  • 如何设置新的ElasticSearchtesting实例? 有没有办法嘲笑它?

  • 你知道的任何gem可以帮助吗?


有些东西,我发现有帮助:

我发现了一篇很好的文章,回答了我所有的问题:)

http://bitsandbit.es/post/11295134047/unit-testing-with-tire-and-elastic-search#disqus_thread

另外,轮胎作者Karmi有一个答案。

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

我不敢相信在问之前我没有find这些…

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

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

例如,你可以创build一个初始化器

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, eg: # 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实例在另一个端口上testing,比如说1234.在你的环境/ test.rb中,你可以设置

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

然后在适当的位置(例如您的testing启动),您可以删除ElasticSearchtesting实例中的所有索引:

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

也许你仍然必须确保你的模型类的轮胎映射定义仍然被调用。

当我在rspec套件中通过轮胎删除我的elasticsearch索引时,我遇到了一个古怪的bug。 在我的Rspecconfiguration中,类似于位和字节博客,我有一个after_each调用清理数据库并清除索引。

我发现我需要调用Tire的create_elasticsearch_index方法,该方法负责读取ActiveRecord类中的映射以设置合适的分析器等。我看到的问题是我的模型中有一些:not_analyzed字段,实际上正在分析这打破了我想如何面对工作)。

开发一切都很好,但testing套件失败了,因为单个单词而不是整个多字串被分解。 在索引被删除之后,似乎rspec中的映射configuration没有被适当地创build。 添加create_elasticsearch_index调用修复了这个问题:

 config.after(:each) do DatabaseCleaner.clean Media.tire.index.delete Media.tire.create_elasticsearch_index end 

媒体是我的模范class。

我碰到类似的问题,这是我如何解决它。 请记住,我的解决schemebuild立在@spaudanjo解决scheme之上。 因为我使用的是spork,所以我在spec_helper.rbSpork.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 

它基本上为每个testing用例定义了自己的唯一前缀,所以在索引中没有。 其他解决scheme都遭遇了一个问题,即使在删除索引之后,Elastic Search也不会刷新索引(即使在运行Model.index.refresh ),这也是随机前缀存在的原因。

它还载入每个模型,并检查它是否响应tire以便我们不再需要在spec_helper.rb和其他区域中保持所有响应轮胎的模型列表。

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

curl -XDELETE 'http://localhost:9200/YOURRAILSNAMEHERE_test_*/'

要findYOURRAILSNAMEHERE ,请运行rails console并运行Rails.application.class.parent_name.downcase 。 输出将是您的项目名称。

Interesting Posts