I use a "fake" smtp server called Dumbster:
http://quintanasoft.com/dumbster/

If run.mode is development or test, my app starts an embedded instance
of dumbster on an unused port and configures Mailer to connect to that
port.  Any email sent by the app is received by dumbster (and not
relayed).  If run.mode=development, I use ActorPing to periodically
iterate over the received messages and log them.  If run.mode=test,
then I leave the messages alone so unit tests can check the message
count and inspect the messages.

Here's some code to get started.

Put this somewhere it'll get executed early (e.g. in Boot):

  Props.mode match {
    case Props.RunModes.Test => LocalSmtp.start(mailPort.get,
LocalSmtp.Mode.Queue)
    case Props.RunModes.Development => LocalSmtp.start(mailPort.get)
  }

And here's a wrapper around Dumbster's SimpleSmtpServer for easy
access to the messages and logging and some other tricks to pop
messages as they are read:

object LocalSmtp extends Actor {

  private var server : Box[SimpleSmtpServer] = Empty
  private val log = LogBoot.loggerByName("LocalSmtp")
  private val logInterval = Helpers.TimeSpan(Helpers.seconds(5))

  var mode : Mode.Value = Mode.Log
  var port : Int = 7725

  object Mode extends Enumeration {
    val Queue = Value(1, "Queue")
    val Log = Value(2, "Log")
  }

  def start(port:Int) : Unit = {
    this.port = port
    start
  }

  def start(port:Int, mode:Mode.Value) : Unit = {
    this.port = port
    this.mode = mode
    start
  }

  override def start = {
    restartServer
    if (mode == Mode.Log) {
      ActorPing.scheduleAtFixedRate(this, LogMessagesEvent,
logInterval, logInterval)
    }
    super.start
  }

  override def exit = {
    stopServer
    super.exit
  }

  private def restartServer {
    stopServer
    server = Full(SimpleSmtpServer.start(port))
  }

  private def stopServer {
    server.map(_.stop)
    server = Empty
  }

  def messages : Iterator[SmtpMessage] = {
    server match {
      case Full(s) => {
        import Conversions._
        val msgs = new IteratorWrapper(s.getReceivedEmail.asInstanceOf
[java.util.Iterator[SmtpMessage]])
        restartServer
        msgs
      }
      case _ => Seq[SmtpMessage]().elements
    }
  }

  def msgCount = server match {
    case Full(s) => s.getReceivedEmailSize
    case _ => 0
  }

  def act = {
    loop {
      react {
        case LogMessagesEvent => if (msgCount > 0) for(msg <-
messages) {
          log.info("RECEIVED EMAIL
---------------------------------------")
          log.info("From: " + msg.getHeaderValue("From"))
          log.info("To: " + msg.getHeaderValue("To"))
          log.info("Subject: " + msg.getHeaderValue("Subject"))
          log.info("Body: " + msg.getBody)
          log.info
("------------------------------------------------------")
        }
        case Scheduled => log.info("LocalSmtp logging is scheduled")
        case any => log.error("LocalSmtp actor received invalid event:
"+any.asInstanceOf[Object].getClass.getName)
      }
    }
  }

  case object LogMessagesEvent
}

On Aug 17, 3:41 pm, Naftoli Gugenheim <[email protected]> wrote:
> How can I test mailing when offline? (Besides having a switch in my program
> to output mailed emails.)It would be nice if you could have all mails
> logged, with all their headers and body, and whether it was sent, preferably
> to a separate log file.

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Lift" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to