You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Tired of spending most of your testing time mocking objects like there's no tomorrow? **Yes.**
11
-
**Moka** provides you with three simple methods to reduce your effort on such a tedious task, and with an incredible abstraction layer between the most popular mock engines and **you**.
11
+
**Moka** provides you with two simple methods to reduce your effort on such a tedious task, and with an incredible abstraction layer between the most popular mock engines and **you**.
12
12
13
13
## Installation
14
14
15
-
You can simply install the package via composer:
15
+
You can install the package via composer:
16
16
17
17
```bash
18
18
composer require --dev facile-it/moka
19
19
```
20
20
21
21
## Usage
22
22
23
-
To use **Moka** in your tests simply `use` the `MokaPHPUnitTrait` (see generators section [below](#strategies)) and run `Moka::clean()` before every test. A simple interface will let you create *moka* (mock) objects, *serve* them easily, and decorate them with *stub* methods with a fluent interface.
24
-
25
-
A complete example follows:
23
+
To use **Moka** in your tests simply `use` function `Moka\Plugin\PHPUnit\moka()` (see generators section [below](#strategies)) and run `Moka::clean()` before every test. A simple interface will let you create *moka* (mock) objects and decorate them with *stub* methods and properties via a fluent interface:
Alternatively, instead of using the trait and `$this->moka(/* ... */)`, you can call `Moka::phpunit(string $fqcnOrAlias, string $alias = null): ProxyInterface`.
57
+
Alternatively, instead of using `moka()`, you can call `Moka::phpunit(string $fqcnOrAlias, string $alias = null): ProxyInterface`.
60
58
61
59
Being such a simple project, **Moka** can be integrated in an already existing test suite with no effort.
62
60
63
-
**Notice:** if you are extending PHPUnit `TestCase`, to simplify the cleaning phase we provide a `MokaCleanerTrait` which automatically runs `Moka::clean()` in `tearDown()`.
64
-
**Warning:** if you are defining your own `tearDown()`, you cannot use the trait!
61
+
**Notice:** if you are extending PHPUnit `TestCase`, to simplify the cleaning phase we provide a `MokaCleanerTrait` which automatically runs `Moka::clean()` after each test.
65
62
66
63
```php
67
64
<?php
68
65
69
66
namespace Foo\Tests;
70
67
71
68
use Moka\Traits\MokaCleanerTrait;
72
-
use Moka\Traits\MokaPHPUnitTrait;
73
69
use PHPUnit\Framework\TestCase;
70
+
use function Moka\Plugin\PHPUnit\moka;
74
71
75
72
class FooTest extends TestCase
76
73
{
77
-
use MokaPHPUnitTrait, MokaCleanerTrait;
74
+
use MokaCleanerTrait;
78
75
79
-
public function setUp()
76
+
protected function setUp()
80
77
{
81
78
// No call to Moka::clean() needed.
82
79
@@ -87,23 +84,23 @@ class FooTest extends TestCase
87
84
}
88
85
```
89
86
90
-
You can rely on the original mock object implementation to be accessible (in the example below, PHPUnit's):
87
+
<aname='original-mock'></a>You can rely on the original mock object implementation to be accessible (in the example below, PHPUnit's - for Prophecy <ahref='#prophecy-mock'>see below</a>):
Creates a proxy containing a mock object (according to the selected strategy) for the provided *FQCN* and optionally assigns an `$alias` to it to be able to get it later:
115
112
116
113
```php
117
-
$mock1 = $this->moka(FooInterface::class)->serve(); // Creates the mock for FooInterface.
118
-
$mock2 = $this->moka(FooInterface::class)->serve(); // Gets a different mock.
114
+
$mock1 = moka(FooInterface::class); // Creates the mock for FooInterface.
115
+
$mock2 = moka(FooInterface::class); // Gets a different mock.
Accepts an array of method or property stubs with format `[$name => $value]`, where `$name`**must** be a string and `$value` can be of any type, including another mock object.
135
134
136
-
Accepts an array of method stubs with format `[$methodName => $methodValue]`, where `$methodName`**must** be a string and `$methodValue` can be of any type, including another mock object or an exception instance:
135
+
**Caution**:
136
+
- Properties are identified by symbol `$` prepended to their names
137
+
- An exception instance set as a method value will be thrown when the method is called
Prophecy lets you stub methods by calling them directly on the `ObjectProphecy`. **Moka** doesn't support such a behavior, but we provide an easy workaround:
176
+
177
+
```php
178
+
// Native Prophecy behavior...
179
+
$this->prophesize(FooInterface::class)
180
+
->someMethod(new AnyValuesToken())
181
+
->willReturn($something);
182
+
183
+
// ...translates to...
184
+
Moka::prophecy(FooInterface::class)
185
+
->someMethod->set(new AnyValuesToken())
186
+
->willReturn($something);
187
+
```
185
188
186
189
## Plugin development
187
190
@@ -212,25 +215,35 @@ Extend `AbstractMockingStrategy` for an easier (and stricter) implementation of
212
215
namespace Moka\Plugin\YourOwn;
213
216
214
217
use Moka\Strategy\AbstractMockingStrategy;
215
-
use Moka\Stub\Stub;
218
+
use Moka\Stub\MethodStub;
216
219
217
220
class YourOwnMockingStrategy extends AbstractMockingStrategy
218
221
{
219
-
public function __construct() {
222
+
public function __construct()
223
+
{
220
224
// TODO: Implement __construct() method.
221
225
}
222
226
223
-
protected function doBuild(string $fqcn) {
227
+
protected function doBuild(string $fqcn)
228
+
{
224
229
// TODO: Implement doBuild() method.
225
230
}
226
231
227
-
protected function doDecorate($mock, Stub $stub) {
228
-
// TODO: Implement doDecorate() method.
232
+
protected function doDecorateWithMethod($mock, MethodStub $stub)
233
+
{
234
+
// TODO: Implement doDecorateWithMethod() method.
229
235
}
230
236
231
-
protected function doGet($mock) {
237
+
protected function doGet($mock)
238
+
{
232
239
// TODO: Implement doGet() method.
233
240
}
241
+
242
+
protected function doCall($mock, string $methodName)
243
+
{
244
+
// Override doCall() if you need special behavior.
0 commit comments