PHPUnit проверяет реальный пример
Я создал класс оболочки mail. Я знаю, что есть много библиотек для отправки электронной почты, но я хочу изучить TDD... Итак, я создал несколько тестов, и у меня есть код. Теперь я могу установить адрес электронной почты в конструкторе и проверить его... если адрес электронной почты ошибочен, возникает исключение. Адрес электронной почты является единственным обязательным полем... У меня нет наборов и нет, потому что пользователь будет настраивать все данные электронной почты на конструкторе.
Теперь я собираюсь написать тесты отправки. Я не знаю, как это начать. Как я могу проверить, существуют ли значения (тема, тело письма, заголовки), если я не хочу иметь сеттеры и получатели? Как я могу проверить, можно ли отправить электронное письмо?
Примеры TDD в реальном мире мне трудны. Я пытался узнать об этом, я прочитал много вещей, но я не могу проверить реальный код.
Спасибо.
Ответы
Ответ 1
Поскольку вы связаны с функцией почты, вызов mail
, скорее всего, будет жестко закодирован в ваш код. Так что посмотрите
Установите расширение testhelper и высмеируйте вызов mail
. Затем дайте фальшивому утверждению, что он вызван с правильными значениями, когда вызывается метод отправки обертки, например. определите пользовательскую функцию почты где-нибудь:
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('[email protected]');
$results = $testClass->send();
// assert the result
$this->assertSame('[email protected]', $results[0]);
$this->assertSame('Default Title', $results[1]);
$this->assertSame('Default Message', $results[2]);
}
Обратите внимание, что вышесказанное предполагает, что ваша функция отправки вернет результат вызова mail()
.
В общем, вы всегда будете пытаться подставить внешнюю подсистему, такую как sendmail или базу данных или файловую систему с Mock или Stub, чтобы вы могли сосредоточиться на тестирование собственного кода в изоляции внешней подсистемы. Вам не нужно проверять, что mail
действительно работает.
Также см. http://www.phpunit.de/manual/3.6/en/test-doubles.html
Ответ 2
В чистом unit test вы действительно не проверяете, было ли отправлено настоящее электронное письмо, а скорее, был ли выбран соответствующий модуль программирования (функция mail
в этом случае). Я действительно не знаю, как проверить, действительно ли функция mail
работает, поскольку у меня нет глубоких знаний о том, как работает электронная почта под капотом. Итак, я просто напишу, как сделать unit test.
Вы можете заставить конструктор класса принять необязательный аргумент - функцию, выполняющую реальную работу по отправке электронной почты. По умолчанию это будет функция 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), но это может быть экземпляр объекта, который вы передадите тестируемому классу.
Ответ 3
Я думаю, что класс должен выполнить проверку для электронной почты, темы и другой информации, поэтому я предлагаю, чтобы это было разделено на функции.
Когда у вас есть частная функция проверки, которая должна возвращать определенный результат, вы можете написать утверждение для его проверки.
эта статья может быть полезна.
Я тоже очень новичок в TDD, и я решил зависеть от IDE (Netbeans), чтобы помочь мне понять этот процесс.
надеюсь, что эта помощь:)