TestContainer::unMock()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
namespace RDV\SymfonyContainerMocks\DependencyInjection;
4
5
use Prophecy\Prophet;
6
use Symfony\Component\DependencyInjection\Container;
7
8
class TestContainer extends Container
9
{
10
    /**
11
     * @var array
12
     */
13
    private $mocked = [];
14
15
    /**
16
     * @var array|null
17
     */
18
    private $parametersOriginal;
19
20
    /**
21
     * @var \ReflectionProperty
22
     */
23
    private $parametersReflection;
24
25
    /**
26
     * @var Prophet
27
     */
28
    protected $prophet;
29
30
    /**
31
     * @param string      $id The service identifier
32
     * @param string|null $class Class or interface fully qualified name
33
     * @return \Prophecy\Prophecy\ObjectProphecy
34
     * @throws \InvalidArgumentException
35
     * @throws \BadMethodCallException
36
     * @throws \Prophecy\Exception\Prophecy\ObjectProphecyException
37
     */
38
    public function prophesize($id, $class = null)
39
    {
40
        if (array_key_exists($id, $this->mocked)) {
41
            throw new \InvalidArgumentException('This service already mocked and can have references');
42
        }
43
44
        if (empty($class)) {
45
            $class = $this->detectClass($id);
46
        }
47
48
        $mock = $this->getProphet()->prophesize($class);
49
        $this->mocked[$id] = $mock->reveal();
50
51
        return $mock;
52
    }
53
54
    /**
55
     * Remove all mocked services
56
     */
57
    public function tearDown()
58
    {
59
        $this->mocked = [];
60
        $this->clearMockedParameters();
61
    }
62
63
    /**
64
     * {@inheritdoc}
65
     */
66
    public function reset()
67
    {
68
        if (interface_exists('Symfony\Component\DependencyInjection\ResettableContainerInterface')
69
            && $this instanceof \Symfony\Component\DependencyInjection\ResettableContainerInterface) {
70
            parent::reset();
71
        }
72
        $this->tearDown();
73
    }
74
75
    /**
76
     * @param string $id
77
     * @param mixed  $mock
78
     */
79
    public function setMock($id, $mock)
80
    {
81
        $this->mocked[$id] = $mock;
82
    }
83
84
    /**
85
     * @param string $id
86
     */
87
    public function unMock($id)
88
    {
89
        unset($this->mocked[$id]);
90
    }
91
92
    /**
93
     * {@inheritdoc}
94
     */
95
    public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE)
96
    {
97
        if (array_key_exists($id, $this->mocked)) {
98
            return $this->mocked[$id];
99
        }
100
101
        return parent::get($id, $invalidBehavior);
102
    }
103
104
    /**
105
     * {@inheritdoc}
106
     */
107
    public function has($id)
108
    {
109
        if (array_key_exists($id, $this->mocked)) {
110
            return true;
111
        }
112
113
        return parent::has($id);
114
    }
115
116
    /**
117
     * {@inheritdoc}
118
     */
119
    public function initialized($id)
120
    {
121
        if (array_key_exists($id, $this->mocked)) {
122
            return true;
123
        }
124
125
        return parent::initialized($id);
126
    }
127
128
    /**
129
     * @return array
130
     */
131
    public function getMockedServices()
132
    {
133
        return $this->mocked;
134
    }
135
136
    /**
137
     * @return Prophet
138
     */
139
    public function getProphet()
140
    {
141
        if (!$this->prophet) {
142
            $this->prophet = new Prophet();
143
        }
144
145
        return $this->prophet;
146
    }
147
148
    /**
149
     * @param string $service
150
     * @return string
151
     * @throws \BadMethodCallException
152
     */
153
    protected function detectClass($service)
154
    {
155
        return DefinitionLoader::getClassName($service, $this);
156
    }
157
158
    /**
159
     * @param string $name
160
     * @param mixed  $value
161
     * @throws \ReflectionException
162
     */
163
    public function setMockedParameter($name, $value)
164
    {
165
        $reflection = $this->getParametersReflection();
166
        $parameters = $reflection->getValue($this);
167
        if (!$this->parametersOriginal) {
168
            $this->parametersOriginal = $parameters;
169
        }
170
        $parameters[$name] = $value;
171
        $reflection->setValue($this, $parameters);
172
    }
173
174
    /**
175
     * @throws \ReflectionException
176
     */
177
    public function clearMockedParameters()
178
    {
179
        if ($this->parametersOriginal) {
180
            $reflection = $this->getParametersReflection();
181
            $reflection->setValue($this, $this->parametersOriginal);
182
            $this->parametersOriginal = null;
183
        }
184
    }
185
186
    /**
187
     * @return \ReflectionProperty
188
     * @throws \ReflectionException
189
     */
190
    private function getParametersReflection()
191
    {
192
        if (!$this->parametersReflection) {
193
            $this->parametersReflection = new \ReflectionProperty($this, 'parameters');
194
            $this->parametersReflection->setAccessible(true);
195
        }
196
197
        return $this->parametersReflection;
198
    }
199
}
200
201