Tôi đang tạo tính năng nhập để nhập tệp CSV vào một vài bảng. Tôi đã tạo một mô-đun có tên là CsvParser
phân tích tệp CSV và tạo bản ghi. Các mô hình của tôi nhận hành động tạo mở rộng CsvParser
. Họ thực hiện cuộc gọi đến CsvParser.create
và chuyển đúng thứ tự thuộc tính và một lambda tùy chọn được gọi là value_parser
. Lambda này biến đổi các giá trị trong một băm thành một định dạng được dựng sẵn.Kiểm tra lambda
class Mutation < ActiveRecord::Base
extend CsvParser
def self.import_csv(csv_file)
attribute_order = %w[reg_nr receipt_date reference_number book_date is_credit sum balance description]
value_parser = lambda do |h|
h["is_credit"] = ((h["is_credit"] == 'B') if h["is_credit"].present?)
h["sum"] = -1 * h["sum"].to_f unless h["is_credit"]
return [h]
end
CsvParser.create(csv_file, self, attribute_order, value_parser)
end
end
Lý do tôi sử dụng lambda thay vì kiểm tra bên trong phương pháp CsvParser.create
là vì lambda giống như quy tắc kinh doanh thuộc về mô hình này.
Câu hỏi của tôi là cách tôi nên kiểm tra lambda này. Tôi có nên thử nghiệm nó trong mô hình hoặc CsvParser? Tôi có nên kiểm tra bản thân lambda hoặc kết quả của một mảng của phương pháp self.import
không? Có lẽ tôi nên tạo cấu trúc mã khác?
My CsvParser trông như sau:
require "csv"
module CsvParser
def self.create(csv_file, klass, attribute_order, value_parser = nil)
parsed_csv = CSV.parse(csv_file, col_sep: "|")
records = []
ActiveRecord::Base.transaction do
parsed_csv.each do |row|
record = Hash.new {|h, k| h[k] = []}
row.each_with_index do |value, index|
record[attribute_order[index]] = value
end
if value_parser.blank?
records << klass.create(record)
else
value_parser.call(record).each do |parsed_record|
records << klass.create(parsed_record)
end
end
end
end
return records
end
end
Tôi đang thử nghiệm các mô-đun riêng của mình: require 'spec_helper'
describe CsvParser do
it "should create relations" do
file = File.new(Rails.root.join('spec/fixtures/files/importrelaties.txt'))
Relation.should_receive(:create).at_least(:once)
Relation.import_csv(file).should be_kind_of Array
end
it "should create mutations" do
file = File.new(Rails.root.join('spec/fixtures/files/importmutaties.txt'))
Mutation.should_receive(:create).at_least(:once)
Mutation.import_csv(file).should be_kind_of Array
end
it "should create strategies" do
file = File.new(Rails.root.join('spec/fixtures/files/importplan.txt'))
Strategy.should_receive(:create).at_least(:once)
Strategy.import_csv(file).should be_kind_of Array
end
it "should create reservations" do
file = File.new(Rails.root.join('spec/fixtures/files/importreservering.txt'))
Reservation.should_receive(:create).at_least(:once)
Reservation.import_csv(file).should be_kind_of Array
end
end
Cám ơn kỹ lưỡng, câu trả lời rõ ràng của bạn. Tôi đã làm theo lời khuyên của bạn và đã có thể kiểm tra hằng số vì tôi có thể gọi Class ::. Tôi chỉ tự hỏi làm thế nào tôi nên kiểm tra một cái gì đó như thế này khi nó sẽ là một biến trong một phương pháp. –
Nếu lambda không thể được refactored ra, tôi sẽ kiểm tra nó như bất kỳ phương pháp khác. Nếu nó là một lambda rất phức tạp, dựa trên rất nhiều biến cục bộ, thì điều này có thể chỉ ra rằng nó muốn là một cá thể riêng của nó. Như một quy luật chung, các phương pháp khó kiểm tra cần một trình tái cấu trúc! – user208769
Hôm nay tôi nhận ra có một cái gì đó gọi là một đối tượng phương pháp. Nó có thể được sử dụng giống như một lambda với sự khác biệt duy nhất mà tôi có thể sử dụng mã của một phương thức thay vì một lambda.Tôi nghĩ nó sạch hơn việc định nghĩa một lambda như một hằng số. Vì vậy, thay vì truyền lambda như một tham số, tôi sử dụng phương thức (:) –