dmurvihill/courier

Testing

Closed this issue · 7 comments

Hi,
did anyone try testing using Mock JavaMail these days? I'm getting an exception on the line val mailer = Mailer("localhost", 25)()

Future(Failure(com.sun.mail.util.MailConnectException: Couldn't connect to host, port: localhost, 25; timeout -1; nested exception is:java.net.ConnectException: Connection refused (Connection refused)))

Then momsInbox is empty.

@mcamou

Hi @Arminea , how are you?

Since you are talking about the Mock, I assuming you are referring to the testing part of the README: https://github.com/dmurvihill/courier#testing.

In this part, we show how to run test using a fake mailer implementation that is provided by a third party library. The doc says that by dropping: libraryDependencies += "org.jvnet.mock-javamail" % "mock-javamail" % "1.9" % "test" in your build.sbt you should be able to run the code in the example without having the Mailer trying to really initiate a connection on localhost:25 (which is your problem, the mock is not used, the mailer tries to connect and fail).

Before we dig into this deeper can you check that:

the exception you are getting comes from test sources (that is scala sources files located under src/test/scala/* and not src/main/scala/*

My first guess is that the line libraryDependencies += "org.jvnet.mock-javamail" % "mock-javamail" % "1.9" % "test" adds a dependency for you test sources and not your regular sources. If the exception you have come from regular sources files (under src/main/scala) then you might want to change the line to (no % "test" at the end):

libraryDependencies += "org.jvnet.mock-javamail" % "mock-javamail" % "1.9"

Hopefully this will help you

Hi, thanks for quick answer :)
I checked location of my file and it is in src/test/scala/*. Also I use gradle but I belive that's not the problem. I just add dependency like this testCompile group: 'org.jvnet.mock-javamail', name: 'mock-javamail', version: '1.9'.

How does it work that the Mailbox stores the messages in memory and the client doesn't automagically connect to localhost without being reconfigured/mocked?

Great, we're confident it's not working hahaha!

It seems like the Transport.send select the transporter dynamically at runtime. Do you mind if I investigate this later today/tomorrow?

I believe that we've updated javax.mail and we did not bother checking the doc and they are outdated. There's probably a little bit of configuration to do use the mocked transport/mailbox.

Well, I was too curious, so I gave it a try. Can you try that (if it works for you, I'll update the documentation):

package courier

import java.util.Properties

import javax.mail.Provider
import org.jvnet.mock_javamail.{Mailbox, MockTransport}
import org.scalatest._

import scala.concurrent.Await
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._

class MockedSMTPProvider extends Provider(Provider.Type.TRANSPORT, "mocked", classOf[MockTransport].getName, "Mock", null)

class MailSpec extends WordSpec {
  private val mockedSession = javax.mail.Session.getDefaultInstance(new Properties() {{
    put("mail.transport.protocol.rfc822", "mocked")
  }})
  mockedSession.setProvider(new MockedSMTPProvider)

  "the mailer" should {
    "send an email" in {
      val mailer = Mailer(mockedSession)
      val future = mailer(Envelope.from("someone@example.com".addr)
            .to("mom@gmail.com".addr)
            .cc("dad@gmail.com".addr)
            .subject("miss you")
            .content(Text("hi mom")))

      Await.ready(future, 5.seconds)
      val momsInbox = Mailbox.get("mom@gmail.com")
      momsInbox.size === 1
      val momsMsg = momsInbox.get(0)
      momsMsg.getContent === "hi mom"
      momsMsg.getSubject === "miss you"
    }
  }
}

Trick is providing a session with a Provider that give the MockTransport implementation (which writes mails to the mocked MailBox. Notice: I have removed the Mailer(localhost, 25)() in favor of Mailer(mockedSession)

I will try it first thing on Monday and I will get back to you with the result :)

Hi,
I tried your code. It worked like charm :)
Thank you very much.

All right, I will fix the documentation. Thanks to you.