我正在学习Scala并写了Email
类看起来像:
class Email(emailConfigName: String) {
private val emailConfig = ConfigFactory.load(emailConfigName) getConfig ("email")
def notifySupportForTenant(symbolicName: String) {
val emailMessage: Message = constructEmailMessage(symbolicName)
Transport.send(emailMessage)
}
def constructEmailMessage(symbolicName: String): Message = {
val message = createMessage(emailConfig getString ("shn.mail.smtp.host"))
message setFrom (new InternetAddress(emailConfig getString ("shn.mail.from")))
// todo: should come from API (sent by client)
message setSentDate (new Date())
message setSubject (emailConfig getString ("shn.mail.subject") replace("TENANT_ID", symbolicName))
message setContent(emailConfig getString ("shn.mail.body"), "text/html")
message.setRecipients(Message.RecipientType.TO, getMessageRecipients(emailConfig getString ("shn.mail.recipient")))
message
}
private def createMessage(smtpHost: String): Message = {
val properties = new Properties()
properties put("mail.smtp.host", smtpHost)
val session = Session.getDefaultInstance(properties, null)
return new MimeMessage(session)
}
private def getMessageRecipients(recipient: String): Array[Address] = {
// had to do the asInstanceOf[...] call here to make scala happy
val addressArray = buildInternetAddressArray(recipient).asInstanceOf[Array[Address]]
if ((addressArray != null) && (addressArray.length > 0)) addressArray
else
throw new IllegalArgumentException("no recipients found to send email")
}
private def buildInternetAddressArray(address: String): Array[InternetAddress] = {
// could test for a null or blank String but I'm letting parse just throw an exception
return InternetAddress.parse(address)
}
}
我想测试这个类的公共API,notifySupportForTenant
,但这不适合单元测试,因为它还会调用Transport.send(emailMessage)
来发送电子邮件。
我有兴趣测试邮件是否构造正确。这意味着我需要测试constructEmailMessage
。
为了测试这个,我不得不将这个public
作为公共接口公开,我不喜欢。我该怎么办?
答案 0 :(得分:6)
在传统的OO中,编程方法通常是私有的,因此它们不能被外部调用并破坏实例的状态。一旦你的方法真的是一个没有副作用的函数(如constructEmailMessage
所示),那么就没有理由将其设为私有。
由于您的目的是学习scala
,我建议您尽可能采用对不可变数据进行操作的函数式样,因为它减轻了OO编程有利于受保护封装的许多原因。
答案 1 :(得分:0)
您可以使用PowerMock库!
import org.powermock.reflect.Whitebox
val email = new Email("lalala@mail.com")
val expected = new Message(...)
val smtpHost = "127.0.0.1"
val actual = Whitebox.invokeMethod(email, "createMessage", smtpHost).asInstanceOf[Message]
assert(actual = expected)
此库也有助于模拟私有方法,但如果您不需要为您执行任务,则可以使用此post中提到的反射。