Completed
Pull Request — master (#114)
by Florian
03:49
created

PayoneObjectManager::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
3
/**
4
 * PAYONE Magento 2 Connector is free software: you can redistribute it and/or modify
5
 * it under the terms of the GNU Lesser General Public License as published by
6
 * the Free Software Foundation, either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * PAYONE Magento 2 Connector is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU Lesser General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Lesser General Public License
15
 * along with PAYONE Magento 2 Connector. If not, see <http://www.gnu.org/licenses/>.
16
 *
17
 * PHP version 5
18
 *
19
 * @category  Payone
20
 * @package   Payone_Magento2_Plugin
21
 * @author    FATCHIP GmbH <[email protected]>
22
 * @copyright 2003 - 2017 Payone GmbH
23
 * @license   <http://www.gnu.org/licenses/> GNU Lesser General Public License
24
 * @link      http://www.payone.de
25
 */
26
27
namespace Payone\Core\Model\Test;
28
29
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
30
31
class PayoneObjectManager extends ObjectManager
32
{
33
    /**
34
     * Class constructor
35
     *
36
     * @param \PHPUnit_Framework_TestCase $testObject
37
     */
38
    public function __construct($testObject)
39
    {
40
        $this->_testObject = $testObject;
0 ignored issues
show
Documentation Bug introduced by
It seems like $testObject of type object<PHPUnit_Framework_TestCase> is incompatible with the declared type object<PHPUnit\Framework\TestCase> of property $_testObject.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
41
    }
42
43
    /**
44
     * Retrieve specific mock of core resource model
45
     *
46
     * @return \Magento\Framework\Module\ResourceInterface|\PHPUnit_Framework_MockObject_MockObject
47
     */
48
    protected function _getResourceModelMock()
49
    {
50
        $resourceMock = $this->_testObject->getMockBuilder(\Magento\Framework\Module\ModuleResource::class)
51
            ->disableOriginalConstructor()
52
            ->disableOriginalClone()
53
            ->disableArgumentCloning()
54
            ->setMethods(['getIdFieldName', '__sleep', '__wakeup'])
55
            ->getMock();
56
        $resourceMock->expects(
57
            $this->_testObject->any()
58
        )->method(
59
            'getIdFieldName'
60
        )->will(
61
            $this->_testObject->returnValue('id')
62
        );
63
64
        return $resourceMock;
65
    }
66
67
    /**
68
     * Retrieve associative array of arguments that used for new object instance creation
69
     *
70
     * @param string $className
71
     * @param array $arguments
72
     * @return array
73
     */
74
    public function getConstructArguments($className, array $arguments = [])
75
    {
76
        $constructArguments = [];
77
        if (!method_exists($className, '__construct')) {
78
            return $constructArguments;
79
        }
80
        $method = new \ReflectionMethod($className, '__construct');
81
82
        foreach ($method->getParameters() as $parameter) {
83
            $parameterName = $parameter->getName();
0 ignored issues
show
Bug introduced by
Consider using $parameter->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
84
            $argClassName = null;
85
            $defaultValue = null;
86
87
            if (array_key_exists($parameterName, $arguments)) {
88
                $constructArguments[$parameterName] = $arguments[$parameterName];
89
                continue;
90
            }
91
92
            if ($parameter->isDefaultValueAvailable()) {
93
                $defaultValue = $parameter->getDefaultValue();
94
            }
95
96
            try {
97
                if ($parameter->getClass()) {
98
                    $argClassName = $parameter->getClass()->getName();
0 ignored issues
show
Bug introduced by
Consider using $parameter->getClass()->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
99
                }
100
                $object = $this->_getMockObject($argClassName, $arguments);
101
            } catch (\ReflectionException $e) {
102
                $parameterString = $parameter->__toString();
103
                $firstPosition = strpos($parameterString, '<required>');
104
                if ($firstPosition !== false) {
105
                    $parameterString = substr($parameterString, $firstPosition + 11);
106
                    $parameterString = substr($parameterString, 0, strpos($parameterString, ' '));
107
                    $object = $this->_testObject->getMockBuilder($parameterString)
108
                        ->disableOriginalConstructor()
109
                        ->disableOriginalClone()
110
                        ->disableArgumentCloning()
111
                        ->getMock();
112
                }
113
            }
114
115
            $constructArguments[$parameterName] = null === $object ? $defaultValue : $object;
0 ignored issues
show
Bug introduced by
The variable $object does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
116
        }
117
        return $constructArguments;
118
    }
119
120
    /**
121
     * Get mock without call of original constructor
122
     *
123
     * @param string $className
124
     * @return \PHPUnit_Framework_MockObject_MockObject
125
     */
126
    protected function _getMockWithoutConstructorCall($className)
127
    {
128
        $mock = $this->_testObject->getMockBuilder($className)
129
            ->disableOriginalConstructor()
130
            ->disableOriginalClone()
131
            ->disableArgumentCloning()
132
            ->getMock();
133
        return $mock;
134
    }
135
136
    /**
137
     * Helper function that creates a mock object for a given class name.
138
     *
139
     * Will return a real object in some cases to assist in testing.
140
     *
141
     * @param string $argClassName
142
     * @param array $arguments
143
     * @return null|object|\PHPUnit_Framework_MockObject_MockObject
144
     */
145
    private function _getMockObject($argClassName, array $arguments)
0 ignored issues
show
Bug introduced by
Consider using a different method name as you override a private method of the parent class.

Overwriting private methods is generally fine as long as you also use private visibility. It might still be preferable for understandability to use a different method name.

Loading history...
146
    {
147
        if (is_subclass_of($argClassName, '\Magento\Framework\Api\ExtensibleObjectBuilder')) {
0 ignored issues
show
Bug introduced by
Due to PHP Bug #53727, is_subclass_of returns inconsistent results on some PHP versions for interfaces; you could instead use ReflectionClass::implementsInterface.
Loading history...
148
            $object = $this->getBuilder($argClassName, $arguments);
149
            return $object;
150
        } else {
151
            $object = $this->_createArgumentMock($argClassName, $arguments);
152
            return $object;
153
        }
154
    }
155
}
156