简体   繁体   English

编写rake任务的单元测试

[英]writing unit test for a rake task

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. 我有一个简单的Rails应用程序,我将数据从csv导入到我的Rails应用程序中,并且运行正常,但是我不知道从哪里开始测试此rake任务以及模块化Rails应用程序的位置。 Any help would be appreciated. 任何帮助,将不胜感激。 Thanks! 谢谢!

csv_importer.task 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 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 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? 如何编写TestCase来捕获此解决方案?

You've actually done the good thing here about keeping all of your task logic in a library file outside rake. 实际上,您已经做好了将所有任务逻辑保存在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. 看到这里我们已经删除了我们如何调用我们的方法(我们不在乎是Rake还是Ruby调用我们的方法),并可能分离了如何获取数据。

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: 鉴于您现在已经分开:

  • how you call your code, because it's away from Rake in a separate library/module 您如何调用代码,因为它不在单独的库/模块中的Rake中
  • how your code gets it's data (normally being provided data by call ... but you can insert data itself here) 您的代码如何获取数据(通常是通过call提供的数据...,但是您可以在此处插入数据本身)

Then you should be all set to go with your test driven design! 然后,您就应该准备好进行测试驱动的设计了!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM