I have a simple rails application where I import data from csv into my rails app which is functioning properly, but I have no idea where to start with testing this rake task, as well as where in a modular rails app. Any help would be appreciated. Thanks!
csv_importer.task
require 'csv_importer/engine'
task users: :environment do
desc 'Import users from csv'
WebImport.new(url: 'http://blablabla/people.csv').call
end
csv_importer.rb
require 'csv_importer/engine'
class WebImport
def initialize(url)
@url = url
end
def call
url = 'http://blablabla/people.csv'
# I forced encoding so avoid UndefinedConversionError "\xC3" from ASCII-8BIT to UTF-8
csv_string = open(url).read.force_encoding('UTF-8')
counter = 0
duplicate_counter = 0
user = []
CSV.parse(csv_string, headers: true, header_converters: :symbol) do |row|
next unless row[:name].present? && row[:email_address].present?
user = CsvImporter::User.create row.to_h
if user.persisted?
counter += 1
else
duplicate_counter += 1
end
end
p "Email duplicate record: #{user.email_address} - #{user.errors.full_messages.join(',')}" if user.errors.any?
p "Imported #{counter} users, #{duplicate_counter} duplicate rows ain't added in total"
end
end
What I have done:
csv_importer_test.rb
require 'test_helper'
require 'rake'
class CsvImporter::Test < ActiveSupport::TestCase
test 'truth' do
assert_kind_of Module, CsvImporter
end
test 'override_application' do
@rake = Rake::Application.new
Rake.application = @rake
assert_equal @rake, Rake.application
end
test '' do
# something here
end
end
This works fine and fills my database. How do I write TestCase to capture this solution?
You've actually done the good thing here about keeping all of your task logic in a library file outside rake. I'd go a little further here...
require 'csv_importer/engine'
class WebImport
def initialize(url)
@url = url
end
def call
url = 'http://blablabla/people.csv'
csv_string = open(url).read.force_encoding('UTF-8')
string_to_users(csv_string)
end
def string_to_users(csv_string)
counter = 0
duplicate_counter = 0
....
end
end
See here that we're removed how we call our method (we don't care if it's Rake or Ruby calling our method) AND potentially separated how we get our data.
Next, I would write my test like the following:
test 'override_application' do
a = WebImport.new(url: 'http://blablabla/people.csv')
a.string_to_users("a,b,c,d,e") # <-- a string you saved from some manual run, or that contains maybe a sample record with their exact format
assert_equal Users.count, 42
end
Given that you've now seperated:
call
... but you can insert data itself here)Then you should be all set to go with your test driven design!