gpt4 book ai didi

unit-testing - 在 CakePHP 中的单元测试期间使用不同的电子邮件配置

转载 作者:行者123 更新时间:2023-12-03 09:26:31 25 4
gpt4 key购买 nike

我在我的一个 Controller 的操作中使用 CakeEmail 类发送电子邮件。在添加电子邮件代码之前,我对该 Controller 进行了单元测试,该测试运行良好。添加电子邮件后,我收到此错误:

SocketException: Could not send email.



这是因为我没有任何方法可以从本地计算机发送电子邮件。

所以我认为在 Config/email.php 中的 EmailConfig 类中有两个不同的配置选项可能是一个好主意(类似于数据库配置文件的工作方式)。默认使用邮件传输,测试使用调试传输。问题在于,与数据库配置不同,Cake 在测试期间不会自动在两者之间切换。

我唯一想到的是在 EmailConfig 类中添加一个构造函数并测试我们是否进行单元测试,但我不确定检查应该是什么。

类似的东西:
class EmailConfig {

public $default = array(
'transport' => 'Mail'
);

public $test = array(
'transport' => 'Debug'
);

public function __construct() {
if ($isUnitTesting) {
$this->default = $this->test;
}
}

}

我上面建议的方法是个好主意吗?如果没有,在单元测试期间,我可以通过哪些其他方式为电子邮件使用不同的传输方式?

更新 - 2012 年 4 月 10 日

我想我以错误的方式解决这个问题。看着 this answer似乎连 $default默认情况下不加载配置,您必须通过调用 CakeEmail::config() 来指定它方法或在构造函数中给出它。所以我认为这给我留下了两个选择:
  • 在 Controller 中检查我们是否在进行单元测试(不知何故?),然后使用“测试”配置。
  • 将我的计算机设置为能够发送电子邮件。

  • 如果我们进行单元测试,我宁愿做第一个但不确定如何在不通过检查膨胀 Controller Action 的情况下完成此操作,这样做似乎是错误的。

    最佳答案

    最简单的方法可能是在测试时切换到 DebugTransport。测试的一部分是您需要将程序设计为可测试的。事实上,Cake 中到处都有一些功能就是为了做到这一点。对于您的应用,假设您在用户注册时发送电子邮件:

    App::uses('CakeEmail', 'Network/Email');
    App::uses('AppController', 'Controller');

    class UsersController extends AppController {

    public function register() {
    //registration logic
    $email = new CakeEmail();
    $email->from(array('site@example.com' => 'Site'));
    $email->to('you@example.com');
    $email->subject('Registered');
    $email->send('Thanks for registering!');
    }

    }

    这看起来无害,但你不能 mock CakeEmail因为它不允许 dependency injection ,这在测试时是必需的。相反, CakeEmail类应该以允许我们稍后更改它的方式实例化。例如:
    App::uses('CakeEmail', 'Network/Email');
    App::uses('AppController', 'Controller');

    class UsersController extends AppController {

    public function register() {
    //registration logic
    $email = $this->_getEmailer();
    $email->from(array('site@example.com' => 'Site'));
    $email->to('you@example.com');
    $email->subject('Registered');
    $email->send('Thanks for registering!');
    }

    public function _getEmailer() {
    return new CakeEmail();
    }

    }

    因为我们添加了一个小辅助函数,我们现在可以测试它(通过模拟辅助函数)。
    App::uses('CakeEmail', 'Network/Email');
    App::uses('UsersController', 'Controller');

    class UsersControllerTest extends ControllerTestCase {

    public function testRegister() {
    $controller = $this->generate('Users', array(
    'methods' => array(
    '_getEmailer'
    )
    ));
    $emailer = new CakeEmail();
    $emailer->transport('Debug');
    $controller
    ->expects($this->any())
    ->method('_getEmailer')
    ->will($this->returnValue($emailer));
    }

    }

    这个测试为我们的 Controller 创建了一个模拟对象,并告诉它返回我们新创建的 $emailer对象时 _getEmailer方法被调用。自 $emailer已将传输设置为“调试”,可以安全进行测试。

    当然,因为现在我们正在决定该方法返回的电子邮件对象,模拟 CakeEmail对象并期望某些返回变得微不足道。

    关于unit-testing - 在 CakePHP 中的单元测试期间使用不同的电子邮件配置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12712865/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com