In Symfony 2.8 we added a feature to easily mock the clock in time sensitive tests. This reduces the risk of having transient tests, which fail randomly and make your test suite unreliable.
Besides time, the network connection is the other main cause of transient tests. That's why Symfony 3.1 adds a feature to mock the network in DNS sensitive tests. Specifically, the PHPUnit Bridge now provides mocks for these PHP functions:
- checkdnsrr
- dns_check_record
- getmxrr
- dns_get_mx
- gethostbyaddr
- gethostbyname
- gethostbynamel
- dns_get_record
Consider the following test that uses the checkMX
option of the Email
constraint to check the validity of the email domain:
1 2 3 4 5 6 7 8 9 10 11 12 13
use Symfony\Component\Validator\Constraints\Email;
class MyTest extends \PHPUnit_Framework_TestCase
{
public function testEmail()
{
$validator = ...
$constraint = new Email(['checkMX' => true]);
$result = $validator->validate('foo@example.com', $constraint);
// ...
}
Add the @dns-sensitive
annotation to the test class to avoid making a real
network connection. Then, use the DnsMock::withMockedHosts()
method to
configure the data you expect to get for the given hosts:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
use Symfony\Component\Validator\Constraints\Email;
/**
* @group dns-sensitive
*/
class MyTest extends \PHPUnit_Framework_TestCase
{
public function testEmails()
{
DnsMock::withMockedHosts(['example.com' => [['type' => 'MX']]]);
$validator = ...
$constraint = new Email(['checkMX' => true]);
$result = $validator->validate('foo@example.com', $constraint);
// ...
}
This test will now execute without making any real network connection. In addition to being faster to execute, this test will never fail again due to the network condition.
The withMockedHosts()
method configuration is defined as an array. The keys
are the mocked hosts and the values are arrays of DNS records in the same format
returned by dns_get_record, so you can simulate diverse network
conditions:
1 2 3 4 5 6
DnsMock::withMockedHosts([
'example.com' => [
['type' => 'A', 'ip' => '1.2.3.4'],
['type' => 'AAAA', 'ipv6' => '::12'],
],
]);
Links to the php documentation are broken, because you added the braces in the URL
@Christophe it's fixed now. Thanks!