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.
-
related (possibly a duplicate): Staying OO and Testable while working with a databasegnat– gnat2015年11月27日 21:06:38 +00:00Commented Nov 27, 2015 at 21:06
1 Answer 1
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.
-
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 thisCreateRefundService
depend on this new DSL class.oldhomemovie– oldhomemovie2015年11月30日 16:43:31 +00:00Commented Nov 30, 2015 at 16:43
Explore related questions
See similar questions with these tags.