我创建了一个mail包装类。我知道有很多库可以发送电子邮件,但我想学习TDD ...所以,我已经创建了一些测试,我有一些代码。现在我可以在构造函数上设置电子邮件地址并验证它...如果电子邮件地址错误,则会出现异常。电子邮件地址是唯一一个必填字段...我没有设置和获取,因为用户将在构造函数上设置所有电子邮件数据。
现在,我要编写发送测试。我不知道如何开始它。如果我不想有定位器和吸气剂,我怎么能测试值是否存在(主题,邮件正文,标题)?我如何测试是否可以发送电子邮件?
现实世界的TDD示例对我来说很难。我试图了解它,我已经阅读了很多东西,但我无法测试真实的代码。
感谢。
答案 0 :(得分:16)
由于您链接到邮件功能,因此对mail
的调用很可能会硬编码到您的代码中。所以看看
安装testhelper extension并模拟对mail
的调用。然后让模拟验证在调用包装器的send方法时,使用正确的值调用它,例如在某处定义自定义邮件功能:
function mail_mock()
{
$allThatWasPassedToTheFunction = func_get_args();
return $allThatWasPassedToTheFunction;
}
然后在send()
测试中,执行类似
public function testSendReceivesExpectedValues()
{
// replace hardcoded call to mail() with mock function
rename_function('mail', 'mail_orig');
rename_function('mail_mock', 'mail');
// use the wrapper
$testClass = new MailWrapper('foo@example.com');
$results = $testClass->send();
// assert the result
$this->assertSame('foo@example.com', $results[0]);
$this->assertSame('Default Title', $results[1]);
$this->assertSame('Default Message', $results[2]);
}
请注意,以上假设您的发送功能将返回mail()
来电的结果。
通常,您将始终尝试替换外部子系统,如sendmail或数据库或具有Mock or a Stub的文件系统,因此您可以专注于独立于外部子系统测试您自己的代码。你不需要测试mail
实际上是否有效。
答案 1 :(得分:2)
在纯单元测试中,您并未真正测试是否已发送真实电子邮件,而是是否已调用相应的编程单元(本例中为mail
函数)。我真的不知道如何测试mail
函数是否真的有效,因为我没有深入了解电子邮件如何工作。所以,我只想写一下如何进行单元测试。
您可以让您的类构造函数接受一个可选参数,该函数可以完成实际发送电子邮件的实际工作。默认情况下,它将是mail
函数,但在您的测试设置中,您将提供实际检查正确主题,正文和标题的特殊函数。
测试:
<?php
class EmailerTest extends PHPUnit_Framework_TestCase
{
public function testMailFunctionIsCalledWithCorrectArguments()
{
$actualSubject, $actualBody, $actualHeaders;
$mailFunction = function ($subject, $body, $headers)
use (&$actualSubject, &$actualBody, &$actualHeaders) {
$actualSubject = $subject;
$actualBody = $body;
$actualHeaders = $headers;
};
$emailer = new Emailer($options, $mailFunction);
$emailer->send();
$this->assertEquals('Expected subject', $actualSubject);
$this->assertEquals('Expected body', $actualBody);
$this->assertEquals('Expected headers', $actualHeaders);
}
}
受测试的课程:
<?php
class Emailer
{
public function __construct($options, $mailFunction = 'mail')
{
$this->subject = $options->subject;
$this->body = $options->body;
// etc.
$this->mailFunction = $mailFunction;
}
public function send()
{
// find out $subject, $body, $headers, and then...
call_user_func_array($this->mailFunction, array(
$subject,
$body,
$headers
));
}
}
这是某种伪代码,因为我已经为你完成或实现了一些值。重点是你应该为你正在测试的类的合作者提供测试双打。
在这种情况下,它只是一个函数(我已经使用了一些PHP 5.3)的功能,但它可能是一个你传递给被测试类的对象实例。
答案 2 :(得分:0)
我认为该课程应该对电子邮件,主题和其他信息进行验证,因此我建议将其分为函数。
当您拥有必须返回特定结果的私有验证函数时,您可以编写断言来测试它。
this article可能有用。
我对TDD也很陌生,我选择依赖IDE(Netbeans)来帮助我理解这个过程。
希望这有帮助:)