11# Introduction
22
3- The package helps mock internal php functions as simple as it can. You can use this package when you need mock such
4- functions as: ` time() ` , ` str_contains() ` and etc.
3+ The package helps mock internal php functions as simple as possible. Use this package when you need mock such
4+ functions as: ` time() ` , ` str_contains() ` , ` rand ` , etc.
55
66## Installation
77
@@ -11,9 +11,9 @@ composer require xepozz/internal-mocker --dev
1111
1212## Usage
1313
14- The main idea is simple: register Listener of PHPUnit and call Mocker at first.
14+ The main idea is pretty simple: register a Listener for PHPUnit and call the Mocker extension first.
1515
16- ### Register hook
16+ ### Register a hook
1717
18181 . Create new file ` tests/MockerExtension.php `
19192 . Paste the following code into the created file:
@@ -58,15 +58,15 @@ Here you have registered extension that will be called every time when you run `
5858
5959The package supports a few ways to mock functions:
6060
61- 1. Runtime mock
62- 2. Pre-defined mock
61+ 1. Runtime mocks
62+ 2. Pre-defined mocks
63633. Mix of two previous ways
6464
65- #### Runtime mock
65+ #### Runtime mocks
6666
6767If you want to make your test case to be used with mocked function you should register it before.
6868
69- Back to the created `MockerExtension::executeBeforeFirstTest` and edit the `$mocks` var .
69+ Back to the created `MockerExtension::executeBeforeFirstTest` and edit the `$mocks` variable .
7070
7171```php
7272$mocks = [
@@ -83,10 +83,10 @@ When you want to mock result in tests you should write the following code into n
8383
8484``` php
8585MockerState::addCondition(
86- 'App\Service',
87- 'time',
88- [],
89- 100
86+ 'App\Service', // namespace
87+ 'time', // function name
88+ [], // arguments
89+ 100 // result
9090);
9191```
9292
@@ -127,9 +127,9 @@ Pre-defined mocks allow you to mock behaviour globally.
127127It means that you don't need to write ` MockerState::addCondition(...) ` into each test case if you want to mock it for
128128whole project.
129129
130- > Keep in the mind that the same function in different namespaces is not the same for ` Mocker ` .
130+ > Keep in mind that the same functions from different namespaces are not the same for ` Mocker ` .
131131
132- So back to the created ` MockerExtension::executeBeforeFirstTest ` and edit the ` $mocks ` var .
132+ So back to the created ` MockerExtension::executeBeforeFirstTest ` and edit the ` $mocks ` variable .
133133
134134``` php
135135$mocks = [
@@ -162,63 +162,49 @@ These methods save "current" state and unload each `Runtime mock` mock that was
162162
163163Using ` MockerState::saveState() ` after ` Mocker->load($mocks) ` saves only ** _ Pre-defined_ ** mocks.
164164
165- ## Restrictions
165+ ## Global namespaced functions
166166
167- You should use function without using root namespace aliasing.
167+ ### Internal functions
168168
169- #### Good example
169+ Without any additional configuration you can mock only functions that are defined under any not global
170+ namespaces: ` App\ ` , ` App\Service\ ` , etc.
171+ But you cannot mock functions that are defined under global namespace or defined in a ` use ` statement, e.g. ` use time; `
172+ or ` \time(); ` .
170173
171- ``` php
172- namespace App\Service
174+ #### Workaround
173175
174- class SomeService
175- {
176- public function doSomething()
177- {
178- // ...
179- time()
180- // ...
181- }
182- }
183- ```
176+ The way you can mock global functions is to disable them
177+ in ` php.ini ` : https://www.php.net/manual/en/ini.core.php#ini.disable-functions
184178
185- #### Bad examples
179+ The best way is to disable them only for tests by running a command with the additional flags:
186180
187- Make sure that function doesn't have leading backslash.
181+ ``` bash
182+ php -ddisable_functions=${functions} ./vendor/bin/phpunit
183+ ```
188184
189- ``` php
190- namespace App\Service
185+ > Replace ` ${functions} ` with the list of functions that you want to mock, separated by commas, e.g.: ` time,rand ` .
191186
192- class SomeService
193- {
194- public function doSomething()
195- {
196- // ...
197- \time()
198- // ...
199- }
200- }
201- ```
187+ So now you can mock global functions as well.
202188
203- Make sure that function isn't included into ` use ` section.
189+ #### Internal function implementation
204190
205- ``` php
206- namespace App\Service
191+ When you disable a function in ` php.ini ` you cannot call it anymore. That means you must implement it by yourself.
207192
208- use function time;
193+ Obviously, almost all functions are implemented in PHP looks the same as the Bash ones.
209194
210- class SomeService
211- {
212- public function doSomething()
213- {
214- // ...
215- time()
216- // ...
217- }
218- }
195+ The shortest way to implement a function is to use ``` `bash command` ``` syntax:
196+
197+ ``` php
198+ $mocks[] = [
199+ 'namespace' => '',
200+ 'name' => 'time',
201+ 'function' => fn () => `date +%s`,
202+ ];
219203```
220204
221- ##### Data Providers
205+ ## Restrictions
206+
207+ ### Data Providers
222208
223209Sometimes you may face unpleasant situation when mocked function is not mocking without forced using ` namespace `
224210+ ` function ` .
@@ -265,5 +251,6 @@ final class MockerExtension implements BeforeTestHook, BeforeFirstTestHook
265251```
266252
267253That all because of PHPUnit 9.5 and lower event management system.
268- Data Provider functionality starts to work before any events so it's impossible to mock the function at the beginning of
254+ Data Provider functionality starts to work before any events, so it's impossible to mock the function at the beginning
255+ of
269256the runtime.
0 commit comments