New in Symfony 3.1: Network mocking and DNS sensitive tests
April 13, 2016 • Published by Javier Eguiluz
Warning: This post is about an unsupported Symfony version. Some of this information may be out of date. Read the most recent Symfony Docs.
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'],
],
]);
Help the Symfony project!
As with any Open-Source project, contributing code or documentation is the most common way to help, but we also have a wide range of sponsoring opportunities.
Comments are closed.
To ensure that comments stay relevant, they are closed for old posts.