Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php declare(strict_types=1);
2
/*
3
 * This file is part of PHPUnit.
4
 *
5
 * (c) Sebastian Bergmann <sebastian@phpunit.de>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
namespace PHPUnit\Framework\MockObject;
11
 
12
use function array_diff;
13
use function array_merge;
14
use PHPUnit\Framework\TestCase;
15
use ReflectionClass;
16
 
17
/**
18
 * @psalm-template MockedType
19
 *
20
 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
21
 */
22
final class MockBuilder
23
{
24
    /**
25
     * @var TestCase
26
     */
27
    private $testCase;
28
 
29
    /**
30
     * @var string
31
     */
32
    private $type;
33
 
34
    /**
35
     * @var null|string[]
36
     */
37
    private $methods = [];
38
 
39
    /**
40
     * @var bool
41
     */
42
    private $emptyMethodsArray = false;
43
 
44
    /**
45
     * @var string
46
     */
47
    private $mockClassName = '';
48
 
49
    /**
50
     * @var array
51
     */
52
    private $constructorArgs = [];
53
 
54
    /**
55
     * @var bool
56
     */
57
    private $originalConstructor = true;
58
 
59
    /**
60
     * @var bool
61
     */
62
    private $originalClone = true;
63
 
64
    /**
65
     * @var bool
66
     */
67
    private $autoload = true;
68
 
69
    /**
70
     * @var bool
71
     */
72
    private $cloneArguments = false;
73
 
74
    /**
75
     * @var bool
76
     */
77
    private $callOriginalMethods = false;
78
 
79
    /**
80
     * @var ?object
81
     */
82
    private $proxyTarget;
83
 
84
    /**
85
     * @var bool
86
     */
87
    private $allowMockingUnknownTypes = true;
88
 
89
    /**
90
     * @var bool
91
     */
92
    private $returnValueGeneration = true;
93
 
94
    /**
95
     * @var Generator
96
     */
97
    private $generator;
98
 
99
    /**
100
     * @param string|string[] $type
101
     *
102
     * @psalm-param class-string<MockedType>|string|string[] $type
103
     */
104
    public function __construct(TestCase $testCase, $type)
105
    {
106
        $this->testCase  = $testCase;
107
        $this->type      = $type;
108
        $this->generator = new Generator;
109
    }
110
 
111
    /**
112
     * Creates a mock object using a fluent interface.
113
     *
114
     * @throws \PHPUnit\Framework\InvalidArgumentException
115
     * @throws ClassAlreadyExistsException
116
     * @throws ClassIsFinalException
117
     * @throws ClassIsReadonlyException
118
     * @throws DuplicateMethodException
119
     * @throws InvalidMethodNameException
120
     * @throws OriginalConstructorInvocationRequiredException
121
     * @throws ReflectionException
122
     * @throws RuntimeException
123
     * @throws UnknownTypeException
124
     *
125
     * @psalm-return MockObject&MockedType
126
     */
127
    public function getMock(): MockObject
128
    {
129
        $object = $this->generator->getMock(
130
            $this->type,
131
            !$this->emptyMethodsArray ? $this->methods : null,
132
            $this->constructorArgs,
133
            $this->mockClassName,
134
            $this->originalConstructor,
135
            $this->originalClone,
136
            $this->autoload,
137
            $this->cloneArguments,
138
            $this->callOriginalMethods,
139
            $this->proxyTarget,
140
            $this->allowMockingUnknownTypes,
141
            $this->returnValueGeneration
142
        );
143
 
144
        $this->testCase->registerMockObject($object);
145
 
146
        return $object;
147
    }
148
 
149
    /**
150
     * Creates a mock object for an abstract class using a fluent interface.
151
     *
152
     * @psalm-return MockObject&MockedType
153
     *
154
     * @throws \PHPUnit\Framework\Exception
155
     * @throws ReflectionException
156
     * @throws RuntimeException
157
     */
158
    public function getMockForAbstractClass(): MockObject
159
    {
160
        $object = $this->generator->getMockForAbstractClass(
161
            $this->type,
162
            $this->constructorArgs,
163
            $this->mockClassName,
164
            $this->originalConstructor,
165
            $this->originalClone,
166
            $this->autoload,
167
            $this->methods,
168
            $this->cloneArguments
169
        );
170
 
171
        $this->testCase->registerMockObject($object);
172
 
173
        return $object;
174
    }
175
 
176
    /**
177
     * Creates a mock object for a trait using a fluent interface.
178
     *
179
     * @psalm-return MockObject&MockedType
180
     *
181
     * @throws \PHPUnit\Framework\Exception
182
     * @throws ReflectionException
183
     * @throws RuntimeException
184
     */
185
    public function getMockForTrait(): MockObject
186
    {
187
        $object = $this->generator->getMockForTrait(
188
            $this->type,
189
            $this->constructorArgs,
190
            $this->mockClassName,
191
            $this->originalConstructor,
192
            $this->originalClone,
193
            $this->autoload,
194
            $this->methods,
195
            $this->cloneArguments
196
        );
197
 
198
        $this->testCase->registerMockObject($object);
199
 
200
        return $object;
201
    }
202
 
203
    /**
204
     * Specifies the subset of methods to mock. Default is to mock none of them.
205
     *
206
     * @deprecated https://github.com/sebastianbergmann/phpunit/pull/3687
207
     *
208
     * @return $this
209
     */
210
    public function setMethods(?array $methods = null): self
211
    {
212
        if ($methods === null) {
213
            $this->methods = $methods;
214
        } else {
215
            $this->methods = array_merge($this->methods ?? [], $methods);
216
        }
217
 
218
        return $this;
219
    }
220
 
221
    /**
222
     * Specifies the subset of methods to mock, requiring each to exist in the class.
223
     *
224
     * @param string[] $methods
225
     *
226
     * @throws CannotUseOnlyMethodsException
227
     * @throws ReflectionException
228
     *
229
     * @return $this
230
     */
231
    public function onlyMethods(array $methods): self
232
    {
233
        if (empty($methods)) {
234
            $this->emptyMethodsArray = true;
235
 
236
            return $this;
237
        }
238
 
239
        try {
240
            $reflector = new ReflectionClass($this->type);
241
            // @codeCoverageIgnoreStart
242
        } catch (\ReflectionException $e) {
243
            throw new ReflectionException(
244
                $e->getMessage(),
245
                $e->getCode(),
246
                $e
247
            );
248
        }
249
        // @codeCoverageIgnoreEnd
250
 
251
        foreach ($methods as $method) {
252
            if (!$reflector->hasMethod($method)) {
253
                throw new CannotUseOnlyMethodsException($this->type, $method);
254
            }
255
        }
256
 
257
        $this->methods = array_merge($this->methods ?? [], $methods);
258
 
259
        return $this;
260
    }
261
 
262
    /**
263
     * Specifies methods that don't exist in the class which you want to mock.
264
     *
265
     * @param string[] $methods
266
     *
267
     * @throws CannotUseAddMethodsException
268
     * @throws ReflectionException
269
     * @throws RuntimeException
270
     *
271
     * @return $this
272
     */
273
    public function addMethods(array $methods): self
274
    {
275
        if (empty($methods)) {
276
            $this->emptyMethodsArray = true;
277
 
278
            return $this;
279
        }
280
 
281
        try {
282
            $reflector = new ReflectionClass($this->type);
283
            // @codeCoverageIgnoreStart
284
        } catch (\ReflectionException $e) {
285
            throw new ReflectionException(
286
                $e->getMessage(),
287
                $e->getCode(),
288
                $e
289
            );
290
        }
291
        // @codeCoverageIgnoreEnd
292
 
293
        foreach ($methods as $method) {
294
            if ($reflector->hasMethod($method)) {
295
                throw new CannotUseAddMethodsException($this->type, $method);
296
            }
297
        }
298
 
299
        $this->methods = array_merge($this->methods ?? [], $methods);
300
 
301
        return $this;
302
    }
303
 
304
    /**
305
     * Specifies the subset of methods to not mock. Default is to mock all of them.
306
     *
307
     * @deprecated https://github.com/sebastianbergmann/phpunit/pull/3687
308
     *
309
     * @throws ReflectionException
310
     */
311
    public function setMethodsExcept(array $methods = []): self
312
    {
313
        return $this->setMethods(
314
            array_diff(
315
                $this->generator->getClassMethods($this->type),
316
                $methods
317
            )
318
        );
319
    }
320
 
321
    /**
322
     * Specifies the arguments for the constructor.
323
     *
324
     * @return $this
325
     */
326
    public function setConstructorArgs(array $args): self
327
    {
328
        $this->constructorArgs = $args;
329
 
330
        return $this;
331
    }
332
 
333
    /**
334
     * Specifies the name for the mock class.
335
     *
336
     * @return $this
337
     */
338
    public function setMockClassName(string $name): self
339
    {
340
        $this->mockClassName = $name;
341
 
342
        return $this;
343
    }
344
 
345
    /**
346
     * Disables the invocation of the original constructor.
347
     *
348
     * @return $this
349
     */
350
    public function disableOriginalConstructor(): self
351
    {
352
        $this->originalConstructor = false;
353
 
354
        return $this;
355
    }
356
 
357
    /**
358
     * Enables the invocation of the original constructor.
359
     *
360
     * @return $this
361
     */
362
    public function enableOriginalConstructor(): self
363
    {
364
        $this->originalConstructor = true;
365
 
366
        return $this;
367
    }
368
 
369
    /**
370
     * Disables the invocation of the original clone constructor.
371
     *
372
     * @return $this
373
     */
374
    public function disableOriginalClone(): self
375
    {
376
        $this->originalClone = false;
377
 
378
        return $this;
379
    }
380
 
381
    /**
382
     * Enables the invocation of the original clone constructor.
383
     *
384
     * @return $this
385
     */
386
    public function enableOriginalClone(): self
387
    {
388
        $this->originalClone = true;
389
 
390
        return $this;
391
    }
392
 
393
    /**
394
     * Disables the use of class autoloading while creating the mock object.
395
     *
396
     * @return $this
397
     */
398
    public function disableAutoload(): self
399
    {
400
        $this->autoload = false;
401
 
402
        return $this;
403
    }
404
 
405
    /**
406
     * Enables the use of class autoloading while creating the mock object.
407
     *
408
     * @return $this
409
     */
410
    public function enableAutoload(): self
411
    {
412
        $this->autoload = true;
413
 
414
        return $this;
415
    }
416
 
417
    /**
418
     * Disables the cloning of arguments passed to mocked methods.
419
     *
420
     * @return $this
421
     */
422
    public function disableArgumentCloning(): self
423
    {
424
        $this->cloneArguments = false;
425
 
426
        return $this;
427
    }
428
 
429
    /**
430
     * Enables the cloning of arguments passed to mocked methods.
431
     *
432
     * @return $this
433
     */
434
    public function enableArgumentCloning(): self
435
    {
436
        $this->cloneArguments = true;
437
 
438
        return $this;
439
    }
440
 
441
    /**
442
     * Enables the invocation of the original methods.
443
     *
444
     * @return $this
445
     */
446
    public function enableProxyingToOriginalMethods(): self
447
    {
448
        $this->callOriginalMethods = true;
449
 
450
        return $this;
451
    }
452
 
453
    /**
454
     * Disables the invocation of the original methods.
455
     *
456
     * @return $this
457
     */
458
    public function disableProxyingToOriginalMethods(): self
459
    {
460
        $this->callOriginalMethods = false;
461
        $this->proxyTarget         = null;
462
 
463
        return $this;
464
    }
465
 
466
    /**
467
     * Sets the proxy target.
468
     *
469
     * @return $this
470
     */
471
    public function setProxyTarget(object $object): self
472
    {
473
        $this->proxyTarget = $object;
474
 
475
        return $this;
476
    }
477
 
478
    /**
479
     * @return $this
480
     */
481
    public function allowMockingUnknownTypes(): self
482
    {
483
        $this->allowMockingUnknownTypes = true;
484
 
485
        return $this;
486
    }
487
 
488
    /**
489
     * @return $this
490
     */
491
    public function disallowMockingUnknownTypes(): self
492
    {
493
        $this->allowMockingUnknownTypes = false;
494
 
495
        return $this;
496
    }
497
 
498
    /**
499
     * @return $this
500
     */
501
    public function enableAutoReturnValueGeneration(): self
502
    {
503
        $this->returnValueGeneration = true;
504
 
505
        return $this;
506
    }
507
 
508
    /**
509
     * @return $this
510
     */
511
    public function disableAutoReturnValueGeneration(): self
512
    {
513
        $this->returnValueGeneration = false;
514
 
515
        return $this;
516
    }
517
}