【问题标题】:writing unit test for a rake task为 rake 任务编写单元测试
【发布时间】:2018-10-17 12:54:14
【问题描述】:

我有一个简单的 rails 应用程序,我将数据从 csv 导入到运行正常的 rails 应用程序中,但我不知道从哪里开始测试这个 rake 任务,以及模块化 rails 应用程序的位置。任何帮助,将不胜感激。谢谢!

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

我做了什么:

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

这很好用,可以填满我的数据库。如何编写 TestCase 来捕获此解决方案?

【问题讨论】:

  • @theTinMan 如果提及您不恰当,我深表歉意。我被告知要寻求你的帮助,因为你的回答往往会教。你能帮我解决这个问题吗?

标签: ruby-on-rails ruby rake rake-task rakefile


【解决方案1】:

实际上,您在这里做了一件好事,将所有任务逻辑保存在 rake 之外的库文件中。我会在这里走得更远一点......

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

看到这里我们删除了我们如何调用我们的方法(我们不关心是 Rake 还是 Ruby 调用我们的方法)并且可能分离了我们如何获取我们的数据。

接下来,我将编写如下测试:

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

鉴于你们现在已经分居:

  • 如何调用代码,因为它与 Rake 不同,位于单独的库/模块中
  • 您的代码如何获取数据(通常由call 提供数据...但您可以在此处自行插入数据)

那么您应该准备好进行测试驱动设计了!

【讨论】:

  • 谢谢。非常面向对象。我有一个错误是NoMethodError: undefined method 'errors' for []:Array,它来自a.string_to_users("a,b,c,d") 行。我在逗号分隔的列表中传递了一些真实数据,但这就是我得到的错误。
  • Well 是在 user = User.create ... 行中创建的,它应该返回一条记录,但是当你运行它时,看起来 Ruby 认为它是一个数组。启动调试器并检查 user 的真正价值是什么,也许这会给你一些洞察力。
  • 是的,它肯定会返回多条记录以供数据库从 csv 文件填充。
猜你喜欢
  • 2012-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-18
  • 2015-12-29
  • 1970-01-01
相关资源
最近更新 更多