测试来自shell Cakephp 3.x的电子邮件

测试来自shell Cakephp 3.x的电子邮件,shell,cakephp,phpunit,cakephp-3.0,Shell,Cakephp,Phpunit,Cakephp 3.0,我想用phpunit和cakephp3.x制作测试用例,shell发送电子邮件。这是我在shell中的函数: class CompaniesShellTest extends TestCase { public function monthlySubscription() { /* .... */ $email = new Email('staff'); try { $email->temp

我想用phpunit和cakephp3.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();
}
但这不起作用。
有什么想法吗?我想检查邮件是否成功发送以及发送了多少次。

您编写代码的方式不起作用

$email = new Email('staff');
以及:

您希望调用的类如何用模拟对象神奇地替换$email变量?您需要重构代码

我会这样做:

首先是订阅邮件。将您的邮件代码放入此邮件器类。这确保了你有很好的分离和可重用的代码

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回调中发送电子邮件(同样使用自定义邮件器类)。检查示例

$email->expects($this->exactly(3))->method('send')->will($this->returnValue(true));