티스토리 뷰

웹어플리케이션에서 JavaMail API를 이용해 email을 전송하는 로직을 테스트하는 practice를 소개하고자 한다.
테스팅 프레임웍은 당연히 junit을 이용하고 JavaMail API의 Session을 웹어플리케이션의 JNDI resource로 등록해놓고 사용하는 환경을 가정하여 테스트했다.

테스트 시나리오는 "andrewxx@hanmail.net"이란 계정으로 "nobodyxx@hanmail.net"에서 메일 제목은 "Hello", 본문은 "Nice to meet you!!"라는 메일을 보내고 그 메일이 제대로 전송되는지를 테스트하는 것이다.
그럼 우선 테스트는 다음과 같이 작성될 수 있다.

MailTest.java

public void testSendMail() {


    SendMailService service = new SendMailService();


    service.send("andrewxx@hanmail.net"


        "nobodyxx@hanmail.net""Hello""Nice to meet you!!");


}


이와 같이 하면 대략 SendMailService.java의 send()는 어떻게 구현이 될껀지 짐작은 될 것이다

Session을 가져오는 부분만 웹어플리케이션에서 JNDI를 통해 가져온다는 것을 가정해서 다음과 같이 작성하면 된다.

SendMailService.java

public void send(String to, String from, String subject, String body) {





    InitialContext initialContext = new InitialContext();


    Context env = (ContextinitialContext.lookup("java:comp/env");


    Session session = (Sessionenv.lookup("mail/Session");


    ...





}


여기까지 해놓고 테스트를 실행하면 JNDI로 "java:comp/env/mail/Session"의 객체를 가져올 수 없다는 에러가 날 것이다. 실제 웹어플리케이션의 JNDI context를 만들어 Session을 등록해주어야 하는데 여기에서 쓸 수 있는게 Springorg.springframework.mock.jndi.SimpleNamingContextBuilder이다.

테스트 코드의 constructor를 다음과 같이 만들어서 Session을 등록하자.

MailTest.java

public MailTest() {





    Properties props = System.getProperties();


    props.put("mail.smtp.host""localhost");


    Session session = Session.getDefaultInstance(props, null);





  try {


    SimpleNamingContextBuilder builder =


    SimpleNamingContextBuilder.emptyActivatedContextBuilder();


    builder.bind("java:comp/env/mail/Session", session);


  catch (NamingException e) {


  }


}


mockobjects에서도 JNDI context에 대한 mock object를 제공하긴 하지만 아직 미완성인 부분들이 많아서 아직 지원하지 않는 method라는 exception을 자주 보게 된다. 반면 Spring의 mock object들은 수는 적지만 완성도가 높아서 상당히 쓸만 하다.

여기까지 했다면 남은 것은 SMTP서버다. SMTP를 이용해 올바른 내용이 전송되어졌는지를 테스트해야하는데 Dumbster - Fake SMTP Server를 이용하면 메일을 실제로 보내서 눈으로 확인하는 테스트를 피할 수 있다. Dumbster는 실제 SMTP서버처럼 25번포트를 통해 들어오는 SMTP메시지를 분석해낼 수 있지만 실제로 메일을 보내지는 않고 메일 정보와 내용을 저장하고 있다가 테스트 코드를 통해 비교해볼 수 있도록 해주는 기능을 가진 테스팅용 SMTP서버이다. 실제 사용예를 보자.

MailTest.java

public class MailTest extends TestCase {


  private SimpleSmtpServer mailServer;





  public MailTest() {


    .... // spring을 이용하여 Session을 등록하는 부분. (생략)


    mailServer = SimpleSmtpServer.start();


  }





  public void testSendMail() {


    SendMailService service = new SendMailService();


    service.send("andrewxx@hanmail.net""nobodyxx@hanmail.net"


      "Hello""Nice to meet you!!");


    assertTrue(mailServer.getReceievedEmailSize() 0);


    Iterator iter = mailServer.getReceivedEmail();


    if (iter.hasNext()) {


      SmtpMessage message = (SmtpMessageiter.next();


      assertEquals("andrewxx@hanmail.net"


        , message.getHeaderValue("To"));


      assertEquals("nobodyxx@hanmail.net"


        , message.getHeaderValue("From"));


      assertEquals("Hello", message.getHeaderValue("Subject"));


      assertTrue(message.getBody().indexOf("Nice to meet you!!")


        >= 0);


    }


  }








  protected void finalize() throws Throwable {


    mailServer.stop();


    super.finalize();


  }


}


constructor에 Dumbster의 SimpleSmtpServer를 시작하는 부분이 있다. 그리고 테스트 코드는 exception이 발생하지 않고 조용히 끝나는 것에 만족할 수도 있지만 실제로 SMTP로 메시지가 제대로 갔는지 확인해보기 위해 몇가지 테스트 코드를 추가했다. Dumbster가 메일을 1개 이상 받았는지 체크한 후에 받는이, 보낸이, 제목, 본문등을 차례로 테스트한것이다. 본문의 경우 multipart로 encoding이 되기 때문에 assertEquals()를 사용할 수 없고 본문 내용이 포함되어있는지만 검사하였다.
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함