Completed
Push — master ( 7ba381...69700f )
by Mike
02:15
created

DoctrineDataCollectorTest::testGetGroupedQueries()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 33
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 33
rs 8.8571
c 0
b 0
f 0
cc 1
eloc 27
nc 1
nop 0
1
<?php
2
3
namespace Doctrine\Bundle\DoctrineBundle\Tests\DataCollector;
4
5
use Doctrine\Bundle\DoctrineBundle\DataCollector\DoctrineDataCollector;
6
use Doctrine\ORM\Mapping\ClassMetadataInfo;
7
use PHPUnit\Framework\TestCase;
8
use Symfony\Component\HttpFoundation\Request;
9
use Symfony\Component\HttpFoundation\Response;
10
11
class DoctrineDataCollectorTest extends TestCase
12
{
13
    const FIRST_ENTITY  = 'TestBundle\Test\Entity\Test1';
14
    const SECOND_ENTITY = 'TestBundle\Test\Entity\Test2';
15
16
    public function testCollectEntities()
17
    {
18
        $manager   = $this->getMockBuilder('Doctrine\ORM\EntityManager')->disableOriginalConstructor()->getMock();
19
        $config    = $this->getMockBuilder('Doctrine\ORM\Configuration')->getMock();
20
        $factory   = $this->getMockBuilder('Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory')
21
            ->setMethods(['getLoadedMetadata'])->getMockForAbstractClass();
22
        $collector = $this->createCollector(['default' => $manager]);
23
24
        $manager->expects($this->any())
25
            ->method('getMetadataFactory')
26
            ->will($this->returnValue($factory));
27
        $manager->expects($this->any())
28
            ->method('getConfiguration')
29
            ->will($this->returnValue($config));
30
31
        if (method_exists($config, 'isSecondLevelCacheEnabled')) {
32
            $config->expects($this->once())
33
                ->method('isSecondLevelCacheEnabled')
34
                ->will($this->returnValue(false));
35
        }
36
37
        $metadatas = [
38
            $this->createEntityMetadata(self::FIRST_ENTITY),
39
            $this->createEntityMetadata(self::SECOND_ENTITY),
40
            $this->createEntityMetadata(self::FIRST_ENTITY),
41
        ];
42
        $factory->expects($this->once())
43
            ->method('getLoadedMetadata')
44
            ->will($this->returnValue($metadatas));
45
46
        $collector->collect(new Request(), new Response());
47
48
        $entities = $collector->getEntities();
49
        $this->assertArrayHasKey('default', $entities);
50
        $this->assertCount(2, $entities['default']);
51
    }
52
53
    public function testGetGroupedQueries()
54
    {
55
        $logger = $this->getMockBuilder('Doctrine\DBAL\Logging\DebugStack')->getMock();
56
        $logger->queries = [];
0 ignored issues
show
Bug introduced by
Accessing queries on the interface PHPUnit\Framework\MockObject\MockObject suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
57
        $logger->queries[] = [
0 ignored issues
show
Bug introduced by
Accessing queries on the interface PHPUnit\Framework\MockObject\MockObject suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
58
            'sql' => 'SELECT * FROM foo WHERE bar = :bar',
59
            'params' => [':bar' => 1],
60
            'executionMS' => 32,
61
        ];
62
        $logger->queries[] = [
0 ignored issues
show
Bug introduced by
Accessing queries on the interface PHPUnit\Framework\MockObject\MockObject suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
63
            'sql' => 'SELECT * FROM foo WHERE bar = :bar',
64
            'params' => [':bar' => 2],
65
            'executionMS' => 25,
66
        ];
67
        $collector = $this->createCollector([]);
68
        $collector->addLogger('default', $logger);
0 ignored issues
show
Documentation introduced by
$logger is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Doctrine\DBAL\Logging\DebugStack>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
69
        $collector->collect(new Request(), new Response());
70
        $groupedQueries = $collector->getGroupedQueries();
71
        $this->assertCount(1, $groupedQueries['default']);
72
        $this->assertSame('SELECT * FROM foo WHERE bar = :bar', $groupedQueries['default'][0]['sql']);
73
        $this->assertSame(2, $groupedQueries['default'][0]['count']);
74
75
        $logger->queries[] = [
0 ignored issues
show
Bug introduced by
Accessing queries on the interface PHPUnit\Framework\MockObject\MockObject suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
76
            'sql' => 'SELECT * FROM bar',
77
            'params' => [],
78
            'executionMS' => 25,
79
        ];
80
        $collector->collect(new Request(), new Response());
81
        $groupedQueries = $collector->getGroupedQueries();
82
        $this->assertCount(2, $groupedQueries['default']);
83
        $this->assertSame('SELECT * FROM bar', $groupedQueries['default'][1]['sql']);
84
        $this->assertSame(1, $groupedQueries['default'][1]['count']);
85
    }
86
87
    /**
88
     * @param string $entityFQCN
89
     *
90
     * @return ClassMetadataInfo
91
     */
92
    private function createEntityMetadata($entityFQCN)
93
    {
94
        $metadata            = new ClassMetadataInfo($entityFQCN);
95
        $metadata->name      = $entityFQCN;
96
        $metadata->reflClass = new \ReflectionClass('stdClass');
97
98
        return $metadata;
99
    }
100
101
    /**
102
     * @param array $managers
103
     *
104
     * @return DoctrineDataCollector
105
     */
106
    private function createCollector(array $managers)
107
    {
108
        $registry = $this->getMockBuilder('Doctrine\Common\Persistence\ManagerRegistry')->getMock();
109
        $registry
110
            ->expects($this->any())
111
            ->method('getConnectionNames')
112
            ->will($this->returnValue(['default' => 'doctrine.dbal.default_connection']));
113
        $registry
114
            ->expects($this->any())
115
            ->method('getManagerNames')
116
            ->will($this->returnValue(['default' => 'doctrine.orm.default_entity_manager']));
117
        $registry
118
            ->expects($this->any())
119
            ->method('getManagers')
120
            ->will($this->returnValue($managers));
121
122
        $collector = new DoctrineDataCollector($registry);
0 ignored issues
show
Documentation introduced by
$registry is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Doctrine\Common\P...stence\ManagerRegistry>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
123
124
        return $collector;
125
    }
126
}
127