0

I have following @Service class that is used to receive feedback, verify its details based on a list of criteria. If verified send that to its recipient.

I am struggling to write a test case for this class. I know there is no need to test external services using Junit. Like sending email in my case but,

  • Whats the best approach to test this class?
  • Should I even test it?
    • If not why?
    • If yes how to complete the test case?

Code

@Service
public class FeedbackServiceImpl implements FeedbackService {

    @Autowired
    private MailSender mailSender;

    @Override
    public boolean sendIt(Feedback feedback)
            throws MailAuthenticationException, CustomException {
        validateEmail(feedback.getEmail());
        try {
            SimpleMailMessage message = new SimpleMailMessage();
            switch (feedback.getRecipient()) {
            case 1:
                message.setTo("jack@project.com"); 
                break;
            case 2:
                message.setTo("norman@project.com");
                break;
            default:
                message.setTo("hello@project.com");
                break;
            }

            message.setCc(feedback.getEmail());
            message.setSubject(subject);
            message.setText(msg);
            mailSender.send(message);

        } catch (MailSendException send) { 
            System.err.println(send.getFailedMessages() + " "
                    + send.getMessage() + " " + feedback);
        }
        return true;

    }

    private void validateEmail(String sender) throws CustomException {
       //make sure provided email is valid
      //this method does verification process against different criteria

    }

}

JUnit

@Test
public void shouldReturnFalseForInvalidFeedbackEmail(){
    MailSender mailSender = Mockito.mock(MailSender.class);
    FeedbackService feedbackSrv = new FeedbackServiceImpl();
    boolean result = feedbackSrv.sendIt(feedback);
    assertTrue(result);
}
Jack
  • 6,430
  • 27
  • 80
  • 151
  • I would use a mock and check that 1/ the message is correctly dispatched (ie. if recipient is 1, sent to jack etc) 2/ MailSendException is properly handled 3/ make `validateEmail` `protected` and test it. NB: it's strange that the `sendIt` method always return true –  Sep 22 '15 at 05:22
  • @Rc If anything goes wrong it throws exception therefore, it just return true. Do you know of any other approach to it? How to test MailSendException? that exception is only passed if MailSender wont be able to send the email. – Jack Sep 22 '15 at 05:24
  • http://docs.mockito.googlecode.com/hg/org/mockito/Mockito.html might be worth a read (there is a `doThrow()`) –  Sep 22 '15 at 05:29

1 Answers1

0

validateEmail which can be tested directly using package private visibility. case and catch can be tested by mocking mailSender (and if really necessary also Feedback).

and that's it what you can unit test. everything else is integration test. if you're making app to send emails with many different configuration using very different settings then i would test it. if you are using just one configuration and one company smtp server and it's unlikely to be changed in the future then maybe it's not worth to set up automatic mailing tests

piotrek
  • 13,982
  • 13
  • 79
  • 165
  • I tried to test the private method to no avail, the question is here, http://stackoverflow.com/questions/32709784/cannot-test-a-class-that-return-a-customexception – Jack Sep 22 '15 at 06:28
  • dont test **private** method. change it to **package private** – piotrek Sep 22 '15 at 06:29
  • I would like to learn more about reflection, thats why I am testing the private method. Also how to test case and catch? would you give me an example? – Jack Sep 22 '15 at 06:33
  • By package private, do you mean default access modifier? – Jack Sep 22 '15 at 06:34