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

时间:2016-08-02 12:46:20

标签: shell cakephp phpunit cakephp-3.0

我想用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();
}

但这不起作用。 有任何想法吗?我想检查邮件是否成功发送以及发送了多少次。

1 个答案:

答案 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