I have a Java EE project with Spring IoC container.
I've just found in Utils
class static method sendMail(long list of params)
. I don't know why but I feel that it would look better if we had separate class (Spring bean with singleton scope) which will be responsible for sending email. But I can't find any arguments which can prove my position.
So, are there any pros (or cons) in using DI in this (rather general) situation?
Util-type classes that hold a mishmash of usually static functions are not generally good things. I've even seen that kind of class named UglyGlobals in one project I worked on. At least they were honest about it! As a general rule, you are correct. Something like mailing is a great candidate for turning into a singleton bean that gets injected.
If the classes that need to send email used a MailSender
interface (sample name) instead of a static Utils.sendMail(...)
method, then you can easily unit test those classes by swapping in a mock/different implementation of MailSender
in your unit tests rather than use the real implementation.
This allows you to test the behavior of those classes when the mail sending succeeds, when an exception/error is caught, etc.
If the classes use a static method like what you've described, then you cannot unit test the behavior of these classes in isolation without actually sending email - at which point it is not an effective, isolated unit test since you will now be dependent on the behavior of 1) the mail-sending code 2) the outgoing mail server, etc.
Yes! I'll give you an example right from my own recent experience.
We recently switched a bunch of apps from sending e-mail directly to using a database queue for sending messages. Messages are queued up in the DB then sent via a batch process. This gives us the ability to handle SMTP server outages, resend messages, control what messages can be sent from our dev server, verify that messages were actually sent, etc.
Something as simple as sending an e-mail can certainly be something you might want to change in the future. Injecting an implementation would make it much easier to do that.
Spring Mail
First I would like to advise you to have a look at the org.springframework.mail package. It provides a helpful utility library for sending email and serves as abstraction to hide specifics of underlying mailing systems.
And since you are already using spring it would mean no pain to use this library as long as it provides everything you need to do with your application regarding sending mail.
Static Methods versus Dependency Injection
Using dependency injection gives you the possibility to easily switch to other implementations. Static method calls bind your implementation of a consumer tightly to the service that the consumer is using.
Testing the consumer means that you will integration test the consumer with the service instead of unit testing your consumer in isolation. This makes you always depend on the underlying logic of those static methods and makes tests possibly fail because of an error in one of those static methods.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With