在没有控制器的情况下测试电子邮件发送
Test email sending with no controller
我的应用程序发送了很多电子邮件。官方文档告诉 how to test emails sending 使用 HTTP 客户端分析器。
但显然我发送的每封电子邮件都没有控制器。
如何测试不是由控制器触发的电子邮件? (我的意思不是来自请求上下文)。
关于我的具体案例的更多细节
我正在使用侦听器触发对正在执行 "email routing"
的服务的调用
我想在这里做的是触发一些事件并检查发送的内容(电子邮件 body、标题、收件人...)
您可能需要考虑设置 global request context,尽管该文档是针对命令的,但应该对您的情况有所帮助,除非您可以提供更多、具体的信息。
首先,您链接的文章是关于功能 (e2e) 测试的,而不是单元。
其次,对于单元测试,您需要在监听器(发送电子邮件)中注入一些 MailerMocker 而不是真正的 Mailer。
例如,您可以像这样创建一个简单的 Mocker
class SwiftMailerTester extends \Swift_Mailer
{
/**
* @var array[\Swift_Mime_Message]
*
*/
protected $sentMessages = array ();
/**
* @var \Swift_Mime_Message
*/
protected $lastSentMessage;
public function __construct() {
}
/**
* Mocks sending message
*
* @param \Swift_Mime_Message $message
* @param null $failedRecepients
*
* @return int
*/
public function send(\Swift_Mime_Message $message, &$failedRecepients = null)
{
$this->lastSentMessage = $message;
$this->sentMessages[] = $message;
return 1;
}
/**
* @return array[\Swift_Mime_Message]
*/
public function getSentMessages()
{
return $this->sentMessages;
}
/**
* @return \Swift_Mime_Message
*/
public function getLastSentMessage()
{
return $this->lastSentMessage;
}
/**
* @return int
*/
public function getSentMessagesCount()
{
return count($this->sentMessages);
}
}
然后在您的单元测试中访问 lastSentMessage(或 sentMessages)以分析 Listener 是否正确完成了工作。
在此之后 great post 我扩展了 Swift_MemorySpool
class CountableMemorySpool extends \Swift_MemorySpool implements \Countable
{
public function count()
{
return count($this->messages);
}
public function getMessages()
{
return $this->messages;
}
}
传递给我的服务使用的邮件程序
class MailServiceTest extends KernelTestCase
{
protected $mailService;
protected $spool;
// ...
protected function setUp()
{
$this->spool = new CountableMemorySpool();
$transport = new \Swift_Transport_SpoolTransport(
new \Swift_Events_SimpleEventDispatcher(),
$this->spool
);
$mailer = new \Swift_Mailer($transport);
$this->mailService->setMailer($mailer);
}
并测试
// ...
public function testMailSpec()
{
// ... Sending the mail ...
$this->assertCount(1, $this->spool,
'Expected exactly one email to be sent');
$msg = $this->spool->getMessages()[0];
$this->assertArrayHasKey('tartempion@test.com', $msg->getTo(),
'Wrong recipient');
$this->assertContains('Tartempion', $msg->getBody(),
'Expected some string contained in the email body');
}
}
我的应用程序发送了很多电子邮件。官方文档告诉 how to test emails sending 使用 HTTP 客户端分析器。
但显然我发送的每封电子邮件都没有控制器。
如何测试不是由控制器触发的电子邮件? (我的意思不是来自请求上下文)。
关于我的具体案例的更多细节
我正在使用侦听器触发对正在执行 "email routing"
的服务的调用
我想在这里做的是触发一些事件并检查发送的内容(电子邮件 body、标题、收件人...)
您可能需要考虑设置 global request context,尽管该文档是针对命令的,但应该对您的情况有所帮助,除非您可以提供更多、具体的信息。
首先,您链接的文章是关于功能 (e2e) 测试的,而不是单元。
其次,对于单元测试,您需要在监听器(发送电子邮件)中注入一些 MailerMocker 而不是真正的 Mailer。
例如,您可以像这样创建一个简单的 Mocker
class SwiftMailerTester extends \Swift_Mailer
{
/**
* @var array[\Swift_Mime_Message]
*
*/
protected $sentMessages = array ();
/**
* @var \Swift_Mime_Message
*/
protected $lastSentMessage;
public function __construct() {
}
/**
* Mocks sending message
*
* @param \Swift_Mime_Message $message
* @param null $failedRecepients
*
* @return int
*/
public function send(\Swift_Mime_Message $message, &$failedRecepients = null)
{
$this->lastSentMessage = $message;
$this->sentMessages[] = $message;
return 1;
}
/**
* @return array[\Swift_Mime_Message]
*/
public function getSentMessages()
{
return $this->sentMessages;
}
/**
* @return \Swift_Mime_Message
*/
public function getLastSentMessage()
{
return $this->lastSentMessage;
}
/**
* @return int
*/
public function getSentMessagesCount()
{
return count($this->sentMessages);
}
}
然后在您的单元测试中访问 lastSentMessage(或 sentMessages)以分析 Listener 是否正确完成了工作。
在此之后 great post 我扩展了 Swift_MemorySpool
class CountableMemorySpool extends \Swift_MemorySpool implements \Countable
{
public function count()
{
return count($this->messages);
}
public function getMessages()
{
return $this->messages;
}
}
传递给我的服务使用的邮件程序
class MailServiceTest extends KernelTestCase
{
protected $mailService;
protected $spool;
// ...
protected function setUp()
{
$this->spool = new CountableMemorySpool();
$transport = new \Swift_Transport_SpoolTransport(
new \Swift_Events_SimpleEventDispatcher(),
$this->spool
);
$mailer = new \Swift_Mailer($transport);
$this->mailService->setMailer($mailer);
}
并测试
// ...
public function testMailSpec()
{
// ... Sending the mail ...
$this->assertCount(1, $this->spool,
'Expected exactly one email to be sent');
$msg = $this->spool->getMessages()[0];
$this->assertArrayHasKey('tartempion@test.com', $msg->getTo(),
'Wrong recipient');
$this->assertContains('Tartempion', $msg->getBody(),
'Expected some string contained in the email body');
}
}