During the process of writing Unit Test for projects, you will inevitably encounter some extremely difficult Unit Test cases, either you have to refactor a lot, or have to switch to writing Feature Test. But the Feature Test doesn’t always work, for example, you need to write tests for Jobs or Models.
Here are some of the cross tests I encountered, note below for easy to find later
Unit Test when Model calls a static function
Here is your Controller:
1 2 3 4 5 6 | <span class="token keyword">use</span> <span class="token package">App Post</span> <span class="token punctuation">;</span> <span class="token variable">$posts</span> <span class="token operator">=</span> Post <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token function">where</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'title'</span> <span class="token punctuation">,</span> <span class="token single-quoted-string string">'like'</span> <span class="token punctuation">,</span> <span class="token double-quoted-string string">"% <span class="token interpolation"><span class="token variable">$keyword</span></span> %"</span> <span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">orderBy</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'created_at'</span> <span class="token punctuation">,</span> <span class="token single-quoted-string string">'ASC'</span> <span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">get</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
In fact, when running Unit Test with a static function call like this, the model will directly query to the Database, making the data retrieved is real data, not fake data using Mockery, making your test not. can run.
The solution to this problem is as follows:
Unit Test
1 2 3 4 5 6 7 8 9 10 11 12 13 | <span class="token keyword">use</span> <span class="token package">Mockery</span> <span class="token punctuation">;</span> <span class="token comment">/** * @runInSeparateProcess * @preserveGlobalState disabled */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">test_it_can_get_posts</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$mockPost</span> <span class="token operator">=</span> Mockery <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token function">mock</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'alias:AppPost'</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token variable">$mockPost</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">shouldReceive</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'where'</span> <span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">andReturn</span> <span class="token punctuation">(</span> Mockery <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token function">mock</span> <span class="token punctuation">(</span> Builder <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token keyword">class</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">//...</span> <span class="token punctuation">}</span> |
By using keyword alias
, you will allow the newly mocked Post object to overwrite the Post object in the controller and don’t forget the two comment lines at the beginning of the function, those two comment lines will help you avoid the error “Object was created”. .
In some cases the way above doesn’t work, you can create a mock as usual then inject it into the Service Container, forcing it to replace the real Object Post that is being used:
1 2 3 4 5 6 7 | <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">test_it_can_get_posts</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$mockPost</span> <span class="token operator">=</span> Mockery <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token function">mock</span> <span class="token punctuation">(</span> Post <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token keyword">class</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">app</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">instance</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'AppPost'</span> <span class="token punctuation">,</span> <span class="token variable">$mockPost</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">//...</span> <span class="token punctuation">}</span> |
Unit Test with callback function
Let’s look at a query like this:
1 2 3 4 5 6 | <span class="token variable">$post</span> <span class="token operator">=</span> Post <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token function">where</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'title'</span> <span class="token punctuation">,</span> <span class="token double-quoted-string string">"% <span class="token interpolation"><span class="token variable">$keyword</span></span> %"</span> <span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">whereHas</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'comments'</span> <span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token variable">$query</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$query</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">where</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'name'</span> <span class="token punctuation">,</span> <span class="token double-quoted-string string">"% <span class="token interpolation"><span class="token variable">$author</span></span> %"</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">get</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
As in the above example, the second parameter of whereHas
is a callback function, in case if you only shouldReceive("whereHas")
then the query line inside the callback will not be tested. Now, let’s test this callback:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <span class="token comment">/** * @runInSeparateProcess * @preserveGlobalState disabled */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">test_it_can_get_posts</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$mockPost</span> <span class="token operator">=</span> Mockery <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token function">mock</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'alias:AppPost'</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token variable">$builder</span> <span class="token operator">=</span> Mockery <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token function">mock</span> <span class="token punctuation">(</span> Builder <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token keyword">class</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token variable">$mockPost</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">shouldReceive</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'where'</span> <span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">andReturn</span> <span class="token punctuation">(</span> <span class="token variable">$builder</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token variable">$mockPost</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">shouldReceive</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'whereHas'</span> <span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">with</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'comments'</span> <span class="token punctuation">,</span> Mockery <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token function">on</span> <span class="token punctuation">(</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token variable">$closure</span> <span class="token punctuation">)</span> <span class="token keyword">use</span> <span class="token punctuation">(</span> <span class="token variable">$builder</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$builder</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">shouldReceive</span> <span class="token punctuation">(</span> <span class="token double-quoted-string string">"where"</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token variable">$closure</span> <span class="token punctuation">(</span> <span class="token variable">$builder</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token boolean constant">true</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">andReturnSelf</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">//...</span> <span class="token punctuation">}</span> |
Using with
to fake the second parameter to whereHas
function, because this parameter is a callback I use Mocker::on()
to create a similar callback, the default parameter of this callback is $closure
, If you dd($closure)
, you should see something like this
1 2 3 4 5 6 7 | <span class="token function">Closure</span> <span class="token punctuation">(</span> <span class="token variable">$query</span> <span class="token punctuation">)</span> <span class="token operator">^</span> <span class="token punctuation">{</span> <span class="token shell-comment comment">#6135</span> <span class="token keyword">class</span> <span class="token punctuation">:</span> <span class="token double-quoted-string string">"AppRepositoriesImplementationsPost"</span> this <span class="token punctuation">:</span> <span class="token keyword">class</span> @anonymous <span class="token package">x00</span> <span class="token operator">/</span> home <span class="token operator">/</span> shroud <span class="token operator">/</span> MyApp <span class="token operator">/</span> myapp <span class="token operator">/</span> tests <span class="token operator">/</span> Unit <span class="token operator">/</span> Repositories <span class="token operator">/</span> Implementations <span class="token operator">/</span> PostTest <span class="token punctuation">.</span> php0x7f1770a82006 <span class="token punctuation">{</span> <span class="token shell-comment comment">#4608 …}</span> file <span class="token punctuation">:</span> <span class="token double-quoted-string string">"./app/Repositories/Implementations/Post.php"</span> line <span class="token punctuation">:</span> <span class="token double-quoted-string string">"121 to 123"</span> <span class="token punctuation">}</span> |
This is a fake closure created by Mockery, it has the same structure as the closure of whereHas
function, with the default parameter also a query builder. Therefore, we need to pass the variable $builder
into the closure of $ closure. The explanation is a bit abstract and confusing noodles, but roughly it helps to fake the query inside that callback.
Unit Test with an array of callback functions
This is the case when you query with the with()
above all else, the typical example would look like this: fetching a list of comments on a post.
1 2 3 4 5 6 7 8 | <span class="token variable">$post</span> <span class="token operator">=</span> Post <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token function">where</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'title'</span> <span class="token punctuation">,</span> <span class="token double-quoted-string string">"% <span class="token interpolation"><span class="token variable">$keyword</span></span> %"</span> <span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">with</span> <span class="token punctuation">(</span> <span class="token punctuation">[</span> <span class="token single-quoted-string string">'comments'</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token variable">$query</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$query</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">where</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'name'</span> <span class="token punctuation">,</span> <span class="token double-quoted-string string">"% <span class="token interpolation"><span class="token variable">$author</span></span> %"</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token punctuation">]</span> <span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">get</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
In this case we will also handle using Mockery::on()
to fake a callback to the with()
function, but with a slight change like this:
1 2 3 4 5 6 7 8 | <span class="token comment">//..</span> <span class="token variable">$mockPost</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">shouldReceive</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'with'</span> <span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">with</span> <span class="token punctuation">(</span> Mockery <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token function">on</span> <span class="token punctuation">(</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token variable">$closure</span> <span class="token punctuation">)</span> <span class="token keyword">use</span> <span class="token punctuation">(</span> <span class="token variable">$builder</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$builder</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">shouldReceive</span> <span class="token punctuation">(</span> <span class="token double-quoted-string string">"where"</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token variable">$closure</span> <span class="token punctuation">[</span> <span class="token single-quoted-string string">'comments'</span> <span class="token punctuation">]</span> <span class="token punctuation">(</span> <span class="token variable">$builder</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token function">is_callable</span> <span class="token punctuation">(</span> <span class="token variable">$closure</span> <span class="token punctuation">[</span> <span class="token single-quoted-string string">'comments'</span> <span class="token punctuation">]</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">andReturnSelf</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
At this point $closure
not an instance of the callback function anymore, but an array of instances, so you need to point to the correct closure of comments
by pointing to the key ‘comments’ as above, and then pass in the query. builder as usual. With return we will check if $ closure with the current key is the correct callback, because maybe Mockery will loop through many different closures, so we need to check with the correct closure of comments to return the result. fruit.
Some other cases
Unit Test with callback in the collection
Consider the following example:
1 2 3 4 5 6 7 | <span class="token variable">$post</span> <span class="token operator">=</span> Post <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token function">where</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'title'</span> <span class="token punctuation">,</span> <span class="token double-quoted-string string">"% <span class="token interpolation"><span class="token variable">$keyword</span></span> %"</span> <span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">get</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">map</span> <span class="token punctuation">(</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token variable">$item</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$item</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">title</span> <span class="token operator">=</span> <span class="token variable">$newTitle</span> <span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token variable">$item</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
Actually, the test cases with the collection are very simple, as long as the input of the collection methods is valid, the test in the collection will run by default. For example, if your query returns a fake value, the map () function will automatically be tested, if you fake the return value is empty, the map () function will not be tested, as follows:
1 2 3 | <span class="token comment">//...</span> <span class="token variable">$builder</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">shouldReceive</span> <span class="token punctuation">(</span> <span class="token double-quoted-string string">"get"</span> <span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">andReturn</span> <span class="token punctuation">(</span> <span class="token function">collect</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// trả về collection rỗng</span> |
Like this, map () will not be tested, let’s return a collection with the same structure as the results returned from the real query, the best way is to use the factory as follows:
1 2 3 4 | <span class="token variable">$posts</span> <span class="token operator">=</span> <span class="token function">factory</span> <span class="token punctuation">(</span> Post <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token keyword">class</span> <span class="token punctuation">,</span> <span class="token number">2</span> <span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">make</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">//lưu ý khi dùng: hàm make() sẽ khởi tạo object Post, còn hàm create() sẽ vừa khởi tạo đối tượng vừa thêm mới một bản ghi vào database</span> <span class="token variable">$builder</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">shouldReceive</span> <span class="token punctuation">(</span> <span class="token double-quoted-string string">"get"</span> <span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">andReturn</span> <span class="token punctuation">(</span> <span class="token variable">$posts</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
This is done
Similar to collection methods with other callbacks like filter (), reduce (), …
Unit Test with query in the loop
Consider the following example again:
1 2 3 4 5 | <span class="token keyword">foreach</span> <span class="token punctuation">(</span> <span class="token variable">$foo</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token variable">$bar</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$post</span> <span class="token operator">=</span> Post <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token function">where</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'title'</span> <span class="token punctuation">,</span> <span class="token double-quoted-string string">"% <span class="token interpolation"><span class="token variable">$keyword</span></span> %"</span> <span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">get</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
Actually, this case is not complicated, you do not need to use the loop in Unit Test, just write the test as usual.
1 2 3 4 5 | <span class="token variable">$mockPost</span> <span class="token operator">=</span> Mockery <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token function">mock</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'alias:AppPost'</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token variable">$builder</span> <span class="token operator">=</span> Mockery <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token function">mock</span> <span class="token punctuation">(</span> Builder <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token keyword">class</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token variable">$mockPost</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">shouldReceive</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'where'</span> <span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">andReturn</span> <span class="token punctuation">(</span> <span class="token variable">$builder</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token variable">$builder</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">shouldReceive</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'get'</span> <span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">andReturn</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
However, be careful when there are more complex queries in a loop, you may also consider refactoring the code if there are too many problems to be resolved.
Fake auth user for the request
In some cases you need to use the login credentials to do something, for example, in unit test you can do the following to fake a login case for the user:
1 2 3 4 5 | <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">get</span> <span class="token punctuation">(</span> Request <span class="token variable">$request</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$user</span> <span class="token operator">=</span> <span class="token variable">$request</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">user</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">//...</span> <span class="token punctuation">}</span> |
Unit Test
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <span class="token keyword">use</span> <span class="token package">App Models User</span> <span class="token punctuation">;</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">test_it_can_get_something</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$user</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">User</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token variable">$user</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">id</span> <span class="token operator">=</span> <span class="token number">1</span> <span class="token punctuation">;</span> <span class="token variable">$request</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Request</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token variable">$request</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">headers</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">set</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'content-type'</span> <span class="token punctuation">,</span> <span class="token single-quoted-string string">'application/json'</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token variable">$request</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">setUserResolver</span> <span class="token punctuation">(</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token keyword">use</span> <span class="token punctuation">(</span> <span class="token variable">$user</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token variable">$user</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token variable">$response</span> <span class="token operator">=</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">controller</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">get</span> <span class="token punctuation">(</span> <span class="token variable">$request</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> |
In the above case, because the get () function accepts the Request parameter, you can set the auth user for the request, but in the case the function does not take the request parameter but use the facade request()
to get the login information. so what?
1 2 3 4 5 | <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">doSth</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$user</span> <span class="token operator">=</span> <span class="token function">request</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">user</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">//...</span> <span class="token punctuation">}</span> |
Now we need to overwrite the instance request
running in the service container with our fake request, like so:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <span class="token keyword">use</span> <span class="token package">App Models User</span> <span class="token punctuation">;</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">test_it_can_get_something</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$user</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">User</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token variable">$user</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">id</span> <span class="token operator">=</span> <span class="token number">1</span> <span class="token punctuation">;</span> <span class="token variable">$request</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Request</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">app</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">instance</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'request'</span> <span class="token punctuation">,</span> <span class="token variable">$request</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// ghi đè instance request</span> <span class="token variable">$request</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">headers</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">set</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'content-type'</span> <span class="token punctuation">,</span> <span class="token single-quoted-string string">'application/json'</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token variable">$request</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">setUserResolver</span> <span class="token punctuation">(</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token keyword">use</span> <span class="token punctuation">(</span> <span class="token variable">$user</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token variable">$user</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token variable">$response</span> <span class="token operator">=</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">controller</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">get</span> <span class="token punctuation">(</span> <span class="token variable">$request</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> |
It is done!
Final
There are many more difficult tests that I can not mention all, after I encounter any more difficult cases, I will definitely write an additional article. Thank you for reading the article!