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 <
naftoli...@gmail.com> 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