Completed
Push — master ( 671e1b...5128a2 )
by Sergey
04:53
created

TestCase::invokeInaccessibleMethod()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 3
1
<?php
2
/**
3
 * Common tests stuff
4
 *
5
 * @see       https://github.com/sergeymakinen/tests
6
 * @copyright Copyright (c) 2017 Sergey Makinen (https://makinen.ru)
7
 * @license   https://github.com/sergeymakinen/tests/blob/master/LICENSE MIT License
8
 */
9
10
namespace SergeyMakinen\Tests;
11
12
abstract class TestCase extends \PHPUnit_Framework_TestCase
13
{
14
    /**
15
     * @var string
16
     */
17
    private $expectedException;
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
18
19
    /**
20
     * @inheritDoc
21
     */
22
    protected function tearDown()
23
    {
24
        parent::tearDown();
25
        $this->expectedException = null;
26
    }
27
28
    /**
29
     * Returns whether the class' parent method exists.
30
     *
31
     * @param string $name
32
     * @return bool
33
     *
34
     * @internal
35
     */
36
    protected function isParentMethod($name)
37
    {
38
        return is_callable('parent::' . $name);
39
    }
40
41
    /**
42
     * Returns a test double for the specified class.
43
     *
44
     * @param string $originalClassName
45
     * @return \PHPUnit_Framework_MockObject_MockObject
46
     */
47
    protected function createMock($originalClassName)
48
    {
49
        if ($this->isParentMethod(__FUNCTION__)) {
50
            return parent::createMock($originalClassName);
51
        }
52
53
        return $this
54
            ->getMockBuilder($originalClassName)
55
            ->disableOriginalConstructor()
56
            ->disableOriginalClone()
57
            ->disableArgumentCloning()
58
            ->getMock();
59
    }
60
61
    /**
62
     * Sets an exception expected.
63
     *
64
     * @param string $exception
65
     * @throws \PHPUnit_Framework_Exception
66
     */
67
    public function expectException($exception)
68
    {
69
        if ($this->isParentMethod(__FUNCTION__)) {
70
            parent::expectException($exception);
71
            return;
72
        }
73
74
        if (!is_string($exception)) {
75
            throw \PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
76
        }
77
78
        $this->expectedException = $exception;
79
        $this->setExpectedException($this->expectedException);
0 ignored issues
show
Deprecated Code introduced by
The method PHPUnit_Framework_TestCase::setExpectedException() has been deprecated with message: Method deprecated since Release 5.2.0

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
80
    }
81
82
    /**
83
     * Sets an exception code expected.
84
     *
85
     * @param int|string $code
86
     * @throws \PHPUnit_Framework_Exception
87
     */
88
    public function expectExceptionCode($code)
89
    {
90
        if ($this->isParentMethod(__FUNCTION__)) {
91
            parent::expectExceptionCode($code);
92
            return;
93
        }
94
95
        if (!is_int($code) && !is_string($code)) {
96
            throw \PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer or string');
97
        }
98
99
        $this->setExpectedException($this->expectedException, '', $code);
0 ignored issues
show
Deprecated Code introduced by
The method PHPUnit_Framework_TestCase::setExpectedException() has been deprecated with message: Method deprecated since Release 5.2.0

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
100
    }
101
102
    /**
103
     * Returns the reflected property.
104
     *
105
     * @param object|string $object
106
     * @param string $name
107
     * @return \ReflectionProperty
108
     */
109
    protected function getProperty($object, $name)
110
    {
111
        $class = new \ReflectionClass($object);
112
        while (!$class->hasProperty($name)) {
113
            $class = $class->getParentClass();
114
        }
115
        return $class->getProperty($name);
116
    }
117
118
    /**
119
     * Returns the private/protected property by its name.
120
     *
121
     * @param object|string $object
122
     * @param string $name
123
     * @return mixed
124
     */
125
    protected function getInaccessibleProperty($object, $name)
126
    {
127
        $property = $this->getProperty($object, $name);
128
        $property->setAccessible(true);
129
        return $property->getValue($object);
130
    }
131
132
    /**
133
     * Sets the private/protected property value by its name.
134
     *
135
     * @param object|string $object
136
     * @param string $name
137
     * @param mixed $value
138
     */
139
    protected function setInaccessibleProperty($object, $name, $value)
140
    {
141
        $property = $this->getProperty($object, $name);
142
        $property->setAccessible(true);
143
        $property->setValue($object, $value);
144
    }
145
146
    /**
147
     * Invokes the private/protected method by its name and returns its result.
148
     * 
149
     * @param object|string $object
150
     * @param string $name
151
     * @param array $args
152
     * @return mixed
153
     */
154
    protected function invokeInaccessibleMethod($object, $name, array $args = [])
155
    {
156
        $method = new \ReflectionMethod($object, $name);
157
        $method->setAccessible(true);
158
        return $method->invokeArgs($object, $args);
159
    }
160
}
161