6

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.

asked Nov 27, 2015 at 18:31
1

1 Answer 1

5

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.

answered Nov 27, 2015 at 19:18
1
  • Thanks, Doc. I went with adding a DSL class, CreateRefundDSL, which have all those methods as public. I have tested (pretty simple unit tests) them each one separately, and made this CreateRefundService depend on this new DSL class. Commented Nov 30, 2015 at 16:43

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.