1 package com.ozacc.mail.mock;
\r
3 import java.io.UnsupportedEncodingException;
\r
4 import java.util.ArrayList;
\r
5 import java.util.List;
\r
6 import java.util.Properties;
\r
8 import javax.mail.MessagingException;
\r
9 import javax.mail.Session;
\r
10 import javax.mail.internet.InternetAddress;
\r
11 import javax.mail.internet.MimeMessage;
\r
13 import com.ozacc.mail.Mail;
\r
14 import com.ozacc.mail.MailBuildException;
\r
15 import com.ozacc.mail.MailException;
\r
16 import com.ozacc.mail.SendMail;
\r
17 import com.ozacc.mail.impl.MimeMessageBuilder;
\r
20 * SendMailImplクラスのMock。<br>
\r
21 * 実存するSMTPサーバを設定しても、実際には送信されません。
\r
22 * デバッグモードを有効にすると、メールを送信するタイミングでコンソールに送信メール内容が出力されます。
\r
24 * Mailインスタンスを addExpectedMail() にセットし verify() メソッドを実行すると、send() されたMailインスタンスと全てのプロパティ(XHeader、添付ファイルを除く)が一致しなければAssertionFailedExceptionがスローされます。
\r
26 * 例えば、send() されたMailインスタンスのFromアドレスと件名だけチェックし、その他のプロパティはチェックしたくない場合は、MockMailインスタンスを使用します。
\r
27 * <pre>Mail sentMail = new Mail();
\r
28 *sentMail.setFrom("from@example.com");
\r
29 *sentMail.setSubject("件名");
\r
30 *sentMail.addTo("to@example.com");
\r
31 *sentMail.setText("動的生成される本文");
\r
33 *Mail expectedMail = new Mail();
\r
34 *expectedMail.setFrom("from@example.com");
\r
35 *expectedMail.setSubject("件名");
\r
37 *MockMail mockMail = new MockMail();
\r
38 *mockMail.setFrom("from@example.com");
\r
39 *mockMail.setSubject("件名");
\r
41 *MockSendMail sendMail = new MockSendMail();
\r
42 *sendMail.addExpectedMail(expectedMail);
\r
43 *sendMail.send(sentMail);
\r
44 *sendMail.verify(); // 失敗 AssertionFailedException
\r
46 *sendMail = new MockSendMail();
\r
47 *sendMail.addExpectedMail(mockMail);
\r
48 *sendMail.send(sentMail);
\r
49 *sendMail.verify(); // 成功</pre>
\r
51 * <strong>注:</strong> 添付ファイルは比較対象になりません。
\r
54 * @author Tomohiro Otsuka
\r
55 * @version $Id: MockSendMail.java,v 1.10.2.1 2004/11/25 08:01:47 otsuka Exp $
\r
57 public class MockSendMail implements SendMail {
\r
59 /** デフォルトのプロトコル。「smtp」 */
\r
60 public static final String DEFAULT_PROTOCOL = "smtp";
\r
62 /** デフォルトのポート。「-1」 */
\r
63 public static final int DEFAULT_PORT = -1;
\r
65 /** デフォルトのSMTPサーバ。「localhost」 */
\r
66 public static final String DEFAULT_HOST = "localhost";
\r
69 public static final String JIS_CHARSET = "ISO-2022-JP";
\r
71 private static final String RETURN_PATH_KEY = "mail.smtp.from";
\r
73 private String protocol = DEFAULT_PROTOCOL;
\r
75 private String host = DEFAULT_HOST;
\r
77 private int port = DEFAULT_PORT;
\r
79 private String username;
\r
81 private String password;
\r
83 private String charset = JIS_CHARSET;
\r
85 private String returnPath;
\r
87 private List sentMails;
\r
89 private List mimeMessages;
\r
91 private List expectedMails;
\r
93 private boolean debug;
\r
98 public MockSendMail() {
\r
104 * MockSendMailインスタンスを初期化します。
\r
106 public void initialize() {
\r
107 sentMails = new ArrayList();
\r
108 expectedMails = new ArrayList();
\r
109 mimeMessages = new ArrayList();
\r
113 * 送信されたメールのMimeMessageインスタンスを返します。
\r
116 * @return 送信メールのMimeMessageインスタンス配列
\r
118 public MimeMessage[] getMimeMessages() {
\r
119 return (MimeMessage[])mimeMessages.toArray(new MimeMessage[mimeMessages.size()]);
\r
123 * 送信されたMailインスタンスを返します。送信順の配列です。
\r
125 * @return 送信メールのMailインスタンス配列
\r
127 public Mail[] getSentMails() {
\r
128 return (Mail[])sentMails.toArray(new Mail[sentMails.size()]);
\r
132 * デバッグモードが有効になっているか判定します。
\r
134 * @return Returns 有効になっている場合 true
\r
136 public boolean isDebug() {
\r
141 * デバッグモード(コンソールにログを出力)を有効にします。
\r
144 * @param debug デバッグモードを有効にする場合 true
\r
146 public void setDebug(boolean debug) {
\r
147 this.debug = debug;
\r
151 * デバッグモードが有効のとき、指定されたメッセージをコンソールに出力します。
\r
153 * @param message コンソール出力するメッセージ
\r
155 private void debug(String message) {
\r
157 System.out.println("[" + Thread.currentThread().getName() + "] DEBUG "
\r
158 + getClass().getName() + " - " + message);
\r
164 * @param expectedMail
\r
166 public void addExpectedMail(Mail expectedMail) {
\r
167 expectedMails.add(expectedMail);
\r
172 * @param expectedMails
\r
174 public void addExpectedMail(Mail[] expectedMails) {
\r
175 for (int i = 0; i < expectedMails.length; i++) {
\r
176 addExpectedMail(expectedMails[i]);
\r
182 * @throws AssertionFailedException
\r
184 public void verify() throws AssertionFailedException {
\r
185 debug("======================================================");
\r
186 debug(" verify() ");
\r
187 debug("======================================================");
\r
190 int numOfExpectedMails = expectedMails.size();
\r
191 int numOfSentMails = sentMails.size();
\r
192 if (numOfExpectedMails != numOfSentMails) {
\r
193 throw new AssertionFailedException("期待メール数<" + numOfExpectedMails + ">と送信メール数<"
\r
194 + numOfSentMails + ">が一致しませんでした。");
\r
197 debug("期待メール数と送信メール数は一致しました。[" + numOfExpectedMails + "通]");
\r
200 for (int i = 0; i < numOfExpectedMails; i++) {
\r
201 Mail expected = (Mail)expectedMails.get(i);
\r
202 Mail sent = (Mail)sentMails.get(i);
\r
203 debug((i + 1) + "通目のチェックを開始します。("
\r
204 + ((expected instanceof MockMail) ? "MockMail" : "Mail") + " - Mail)");
\r
205 checkEquality(expected, sent, i + 1);
\r
206 debug((i + 1) + "通目の期待メールと送信メール内容は一致しました。");
\r
209 debug("verifyプロセスは全て成功しました。");
\r
210 debug("======================================================");
\r
216 * @throws AssertionFailedException
\r
218 public void checkEquality(Mail expected, Mail sent, int num) throws AssertionFailedException {
\r
219 boolean mockMode = (expected instanceof MockMail);
\r
222 if (expected.isMultipartMail()) {
\r
226 if ((expected.getHtmlText() == null && sent.getHtmlText() != null)
\r
227 || (expected.getHtmlText() != null && sent.getHtmlText() == null)
\r
228 || (!expected.getHtmlText().equals(sent.getHtmlText()))) {
\r
229 throwExceptioWithMessage("HTML本文", expected.getHtmlText(), sent.getHtmlText(),
\r
232 } else if (mockMode && expected.getHtmlText() != null) {
\r
233 if (!expected.getHtmlText().equals(sent.getHtmlText())) {
\r
234 throwExceptioWithMessage("HTML本文", expected.getHtmlText(), sent.getHtmlText(),
\r
241 if (!mockMode || (mockMode && expected.getReturnPath() != null)) {
\r
242 if (expected.getReturnPath() != null && sent.getReturnPath() != null) {
\r
243 if (!expected.getReturnPath().equals(sent.getReturnPath())) {
\r
244 throwExceptioWithMessage("Return-Pathアドレス", expected.getReturnPath()
\r
245 .toUnicodeString(), sent.getReturnPath().toUnicodeString(), num);
\r
247 } else if ((expected.getReturnPath() != null && sent.getReturnPath() == null)
\r
248 || (expected.getReturnPath() == null && sent.getReturnPath() != null)) {
\r
249 throw new AssertionFailedException();
\r
254 if (!mockMode || (mockMode && expected.getFrom() != null)) {
\r
255 if (expected.getFrom() != null && sent.getFrom() != null) {
\r
256 if (!EqualityCheck.equals(expected.getFrom(), sent.getFrom())) {
\r
257 throwExceptioWithMessage("Fromアドレス", expected.getFrom().toUnicodeString(), sent
\r
258 .getFrom().toUnicodeString(), num);
\r
260 } else if ((expected.getFrom() != null && sent.getFrom() == null)
\r
261 || (expected.getFrom() == null && sent.getFrom() != null)) {
\r
262 throw new AssertionFailedException();
\r
267 InternetAddress[] expectedAddresses = expected.getTo();
\r
268 InternetAddress[] sentAddresses = sent.getTo();
\r
269 if (!mockMode || (mockMode && expectedAddresses.length > 0)) {
\r
270 if (expectedAddresses.length != sentAddresses.length) {
\r
271 throwExceptioWithMessage("Toアドレス数", Integer.toString(expectedAddresses.length),
\r
272 Integer.toString(sentAddresses.length), num);
\r
274 for (int i = 0; i < expectedAddresses.length; i++) {
\r
275 if (!EqualityCheck.equals(expectedAddresses[i], sentAddresses[i])) {
\r
276 throwExceptioWithMessage("Toアドレス", expectedAddresses[i].toUnicodeString(),
\r
277 sentAddresses[i].toUnicodeString(), num);
\r
283 expectedAddresses = expected.getCc();
\r
284 sentAddresses = sent.getCc();
\r
285 if (!mockMode || (mockMode && expectedAddresses.length > 0)) {
\r
286 if (expectedAddresses.length != sentAddresses.length) {
\r
287 throwExceptioWithMessage("Ccアドレス数", Integer.toString(expectedAddresses.length),
\r
288 Integer.toString(sentAddresses.length), num);
\r
290 for (int i = 0; i < expectedAddresses.length; i++) {
\r
291 if (!EqualityCheck.equals(expectedAddresses[i], sentAddresses[i])) {
\r
292 throwExceptioWithMessage("Ccアドレス", expectedAddresses[i].toUnicodeString(),
\r
293 sentAddresses[i].toUnicodeString(), num);
\r
299 expectedAddresses = expected.getBcc();
\r
300 sentAddresses = sent.getBcc();
\r
301 if (!mockMode || (mockMode && expectedAddresses.length > 0)) {
\r
302 if (expectedAddresses.length != sentAddresses.length) {
\r
303 throwExceptioWithMessage("Bccアドレス数", Integer.toString(expectedAddresses.length),
\r
304 Integer.toString(sentAddresses.length), num);
\r
306 for (int i = 0; i < expectedAddresses.length; i++) {
\r
307 if (!EqualityCheck.equals(expectedAddresses[i], sentAddresses[i])) {
\r
308 throwExceptioWithMessage("Bccアドレス", expectedAddresses[i].toUnicodeString(),
\r
309 sentAddresses[i].toUnicodeString(), num);
\r
315 if (!mockMode || (mockMode && expected.getReplyTo() != null)) {
\r
316 if (expected.getReplyTo() != null && sent.getReplyTo() != null) {
\r
317 if (!EqualityCheck.equals(expected.getReplyTo(), sent.getReplyTo())) {
\r
318 throwExceptioWithMessage("ReplyToアドレス",
\r
319 expected.getReplyTo().toUnicodeString(), sent.getReplyTo()
\r
320 .toUnicodeString(), num);
\r
322 } else if ((expected.getReplyTo() != null && sent.getReplyTo() == null)
\r
323 || (expected.getReplyTo() == null && sent.getReplyTo() != null)) {
\r
324 throw new AssertionFailedException();
\r
329 if (!mockMode || (mockMode && expected.getSubject().length() > 0)) {
\r
330 if (!expected.getSubject().equals(sent.getSubject())) {
\r
331 throwExceptioWithMessage("件名", expected.getSubject(), sent.getSubject(), num);
\r
336 if (!mockMode || (mockMode && expected.getText().length() > 0)) {
\r
337 if (!expected.getText().equals(sent.getText())) {
\r
338 throwExceptioWithMessage("本文", expected.getText(), sent.getText(), num);
\r
345 * 引数の値を受けてエラーメッセージを生成し、AssertionFailedErrorをスローします。
\r
347 * @param name 一致しなかった項目名
\r
348 * @param expectedValue 期待値
\r
349 * @param sentValue 実際値
\r
350 * @param num N番目のメール
\r
351 * @throws AssertionFailedException 生成された例外
\r
353 protected void throwExceptioWithMessage(String name, String expectedValue, String sentValue,
\r
354 int num) throws AssertionFailedException {
\r
355 String message = num + "番目のメッセージで、「" + name + "」が一致しませんでした。期待値='" + expectedValue
\r
356 + "', 送信値='" + sentValue + "'";
\r
359 debug("verifyプロセスは失敗しました。");
\r
360 debug("******************************************************");
\r
362 throw new AssertionFailedException(message);
\r
366 * @see com.ozacc.mail.SendMail#send(com.ozacc.mail.Mail)
\r
368 public void send(Mail mail) throws MailException {
\r
369 send(new Mail[] { mail });
\r
373 * @see com.ozacc.mail.SendMail#send(com.ozacc.mail.Mail[])
\r
375 public void send(Mail[] mails) throws MailException {
\r
376 debug("SMTPサーバ[" + host + "]に接続するフリ。");
\r
377 debug("SMTPサーバ[" + host + "]に接続したフリ。");
\r
379 Session session = Session.getInstance(new Properties());
\r
380 for (int i = 0; i < mails.length; i++) {
\r
382 Mail mail = mails[i];
\r
385 MimeMessage message = new MimeMessage(session);
\r
386 MimeMessageBuilder builder = new MimeMessageBuilder(message);
\r
388 builder.buildMimeMessage(mail);
\r
389 } catch (UnsupportedEncodingException e) {
\r
390 throw new MailBuildException("サポートされていない文字コードが指定されました。", e);
\r
391 } catch (MessagingException e) {
\r
392 throw new MailBuildException("MimeMessageの生成に失敗しました。", e);
\r
394 mimeMessages.add(message);
\r
396 debug("メールを送信するフリ。");
\r
397 sentMails.add(mail);
\r
398 debug(mail.toString());
\r
399 debug("メールを送信したフリ。");
\r
402 debug("SMTPサーバ[" + host + "]との接続を切断するフリ。");
\r
403 debug("SMTPサーバ[" + host + "]との接続を切断したフリ。");
\r
407 * @see com.ozacc.mail.SendMail#send(javax.mail.internet.MimeMessage)
\r
409 public void send(MimeMessage mimeMessage) throws MailException {
\r
410 throw new UnsupportedOperationException("申し訳ございません。MockSendMailでは、このメソッドをサポートしていません。");
\r
414 * @see com.ozacc.mail.SendMail#send(javax.mail.internet.MimeMessage[])
\r
416 public void send(MimeMessage[] mimeMessages) throws MailException {
\r
417 throw new UnsupportedOperationException("申し訳ございません。MockSendMailでは、このメソッドをサポートしていません。");
\r
421 * エンコーディングに使用する文字コードを返します。
\r
423 * @return エンコーディングに使用する文字コード
\r
425 public String getCharset() {
\r
430 * メールの件名や本文のエンコーディングに使用する文字コードを指定します。
\r
431 * デフォルトは ISO-2022-JP です。
\r
433 * @param charset エンコーディングに使用する文字コード
\r
435 public void setCharset(String charset) {
\r
436 this.charset = charset;
\r
440 * セットされたSMTPサーバのホスト名、またはIPアドレスを返します。
\r
442 * @return SMTPサーバのホスト名、またはIPアドレス
\r
444 public String getHost() {
\r
449 * SMTPサーバのホスト名、またはIPアドレスをセットします。
\r
450 * デフォルトは localhost です。
\r
452 * @param host SMTPサーバのホスト名、またはIPアドレス
\r
454 public void setHost(String host) {
\r
459 * @return SMTPサーバ認証パスワード
\r
461 public String getPassword() {
\r
466 * SMTPサーバの接続認証が必要な場合にパスワードをセットします。
\r
468 * @param password SMTPサーバ認証パスワード
\r
470 public void setPassword(String password) {
\r
471 this.password = password;
\r
475 * @return SMTPサーバのポート番号
\r
477 public int getPort() {
\r
482 * SMTPサーバのポート番号をセットします。
\r
484 * @param port SMTPサーバのポート番号
\r
486 public void setPort(int port) {
\r
491 * @return Returns the protocol.
\r
493 public String getProtocol() {
\r
498 * @param protocol The protocol to set.
\r
500 public void setProtocol(String protocol) {
\r
501 this.protocol = protocol;
\r
505 * @return Return-Pathアドレス
\r
507 public String getReturnPath() {
\r
512 * Return-Pathアドレスをセットします。
\r
514 * @param returnPath Return-Pathアドレス
\r
516 public void setReturnPath(String returnPath) {
\r
517 this.returnPath = returnPath;
\r
521 * @return SMTPサーバ認証ユーザ名
\r
523 public String getUsername() {
\r
528 * SMTPサーバの接続認証が必要な場合にユーザ名をセットします。
\r
530 * @param username SMTPサーバ認証ユーザ名
\r
532 public void setUsername(String username) {
\r
533 this.username = username;
\r