Closed VoTaiTri closed 8 years ago
Extract this code into a normal module or class, and test it normally. Then call that code from your rake task.
e.g:
# lib/crawler.rb
class Crawler
def self.area_names
area_names = Dir[Rails.root.join("lib", "crawler", "*.rb")].map do |file_name|
File.basename(file_name, ".rb")
end
area_names.delete("base")
area_names
end
def perform
logger = Logger.new("log/crawl_#{area_name}.log")
area_class = area_name.to_s.camelize
crawler = "Crawler::#{area_class}".safe_constantize.new logger
scraper = "Scraper::#{area_class}".safe_constantize.new logger
parallel_results = crawler.crawl
mutex = Mutex.new
current_time = Time.zone.now
Parallel.each(parallel_results, in_threads: [parallel_results.count, CRAWL_CONFIG["building_thread_max"]].min) do |pages|
begin
pages.each do |page|
available_infos = scraper.scrape page
mutex.synchronize do
ActiveRecord::Base.connection_pool.with_connection do
Availability.insert_each_ground_data available_infos
end
end
end
rescue => e
logger.error e.message
e.backtrace.each{|line| logger.error line}
raise e
end
end
admin_id = "Scraper::#{area_class}".safe_constantize::ADMINISTRATOR_ID
ground_ids = CrawlMapping.where(administrator_id: admin_id).pluck(:ground_id)
Availability.update_no_available_for_not_updated_by_grounds_and_time ground_ids, current_time
end
end
# lib/tasks/crawler.rake
namespace :crawler do
Crawler.area_names.each do |name|
task name.to_sym => :environment do
Crawler.new(name).perform
end
end
end
@JonRowe thanks you so much
i have
crawler.rake
like that:available_infos
here is array set ofEnumerator
with this source code, i'll stop if i get exception andraise
error in rspec, i only need pass input is status of action (my app raise error or no) and check result of these case - change of database herei'll run method
update_no_available_for_not_updated_by_grounds_and_time
to updata database if every thing return ok and opposite. so how can i fake these cases to test? can you help me write rpsec for it! thanks.