を読んで、「自分なら設計を変えて、publicにしてからテストを書くなー」と思ったので、考え方・直し方の一例としてブログを書く。
元の設計
元記事のスライドの途中に出てくるコードはこんな感じで、バッチ処理などでよくある設計。
module Tasks module Hoge class Sender def self.execute data = aggregate_data processed_data = process_data(data) send_s3(processed_data) end end end end
コードの臭い
個人的なリファクタリング原則で「引数が1つのメソッドは、その引数のインスタンスメソッドに書き換えられる」がある。*1
あと、元コードだと「データ収集、加工、s3に置く」のが1メソッドになっていてテストし辛いので、そこも分ける。
module Tasks module Hoge class Sender def self.execute instance.process_data.send_s3 end def self.instance data = aggregate_data new(data) end def self.aggregate_data # データを集める処理 end def initialize(data) @data = data end attr_reader :data def process_data processed = data.group_by(&:first) .sort .map { |key, value| [values[0], values[1]] } # Immutableの方がメンテしやすいので、新しいインスタンスを返す設計にしてある Sender.new(processed) end def send_s3 # s3に置く処理 end end end end
この構造にすると、データ収集・加工・s3アップロードをそれぞれテストしやすくなる。
まとめ
単にpublicに変えるわけじゃなくて、設計を見直した結果publicになるものかなと思ってます。
*1:個人的によく使う原則なんだけど、何か名前あったりするのかな