我想用phpunit和cakephp 3.x制作测试用例,发送电子邮件的shell。这是我的shell函数:
class CompaniesShellTest extends TestCase
{
public function monthlySubscription()
{
/* .... */
$email = new Email('staff');
try {
$email->template('Companies.alert_renew_success', 'base')
->theme('Backend')
->emailFormat('html')
->profile(['ElasticMail' => ['channel' => ['alert_renew_success']]])
->to($user->username)
//->to('dario@example.com')
->subject('Eseguito rinnovo mensile abbonamento')
->viewVars(['company' => $company, 'user' => $user])
->send();
} catch (Exception $e) {
debug($e);
}
/* ... */
}
}
在我的测试课中,我有这个功能
/**
* setUp method
*
* @return void
*/
public function setUp()
{
parent::setUp();
$this->io = $this->getMockBuilder('Cake\Console\ConsoleIo')->getMock();
$this->CompaniesShell = new CompaniesShell($this->io);
}
/**
* tearDown method
*
* @return void
*/
public function tearDown()
{
unset($this->CompaniesShell);
parent::tearDown();
}
/**
* Test monthlySubscription method
*
* @return void
*/
public function testMonthlySubscription()
{
$email = $this->getMock('Cake\Mailer\Email', array('subject', 'from', 'to', 'send'));
$email->expects($this->exactly(3))->method('send')->will($this->returnValue(true));
$this->CompaniesShell->MonthlySubscription();
}
但这不起作用。 有任何想法吗?我想检查邮件是否成功发送以及发送了多少次。
答案 0 :(得分:3)
你编写代码的方式不会起作用。
$email = new Email('staff');
和
$email = $this->getMock('Cake\Mailer\Email', array('subject', 'from', 'to', 'send'));
您如何期望您调用的类用模拟对象神奇地替换$ email变量?您需要重构代码。
我就是这样做的:
首先implement a custom mailer,如SubscriptionMailer。将您的邮件代码放入此邮件程序类。这可以确保您拥有漂亮的可分离和可重复使用的代码。
public function getMailer() {
return new SubscriptionMailer();
}
在你的测试中模拟shell的getMailer()方法并返回你的电子邮件模拟。
$mockShell->expects($this->any())
->method('getMailer')
->will($this->returnValue($mailerMock));
然后你可以做你已经拥有的期望。
$email->expects($this->exactly(3))->method('send')->will($this->returnValue(true));
另外,根据shell方法的作用,最好是在从shell处理数据的模型对象(表)的afterSave回调(再次使用自定义邮件程序类)中发送电子邮件。查看示例at the end of this page。