Question

TL;DR. Writing procedural code within a DB transaction. How can I improve design of the code so it's better testable?

In my application I have a service object that perform multiple things within the same transaction. See code in Ruby below:

class CreateRefundService
  def create(customer_id)
    ActiveRecord::Base.transaction do
      refund = create_refund(customer_id)
      credit = add_credits_to_customer(customer_id)

      send_email(refund)
      add_note(refund, credit)
    end
  end

  private

  # ... implementation of all 4 methods above
end

I'm trying to write 4 tests that would check that all four things happen during transaction, but it starts to feel uncomfortable, since for every method under test I need to stub other 3 methods. This gives me a warrant that there's probably a problem about this design.

I'm under constraints that multiple things need to happen during the same transaction.

Était-ce utile?

La solution

The four methods seem to do things which make sense each on its own. So I would not see them as "implementation details which must kept private", I would see them as individual, reusable units, each unit worth to be tested on its own. So you can make them public and write a unit test directly for each.

What remains is to decide if you need some kind of automated integration test for the create method, or if you rely other tests on a different layer or level for this method.

Licencié sous: CC-BY-SA avec attribution
scroll top