Hello anh em. Ở bài này mình tiếp tục chia sẻ một số kiến thức về viết test cho project laravel. Mình sẽ hướng dẫn cách viết test 1 repository trong laravel.
1. Chuẩn bị
Để có thể test repository thì trước hết mình cần có repository để test, ở đây mình sẽ tạo userRepository và sau đó viết test cho nó.
- Trước hết mình sẽ tạo baseRepository như sau
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | <span class="token php language-php"><span class="token delimiter important"><?php</span> <span class="token keyword">namespace</span> <span class="token package">App<span class="token punctuation"></span>Repositories<span class="token punctuation"></span>Eloquents</span><span class="token punctuation">;</span> <span class="token keyword">use</span> <span class="token package">App<span class="token punctuation"></span>Repositories<span class="token punctuation"></span>Interfaces<span class="token punctuation"></span>BaseRepositoryInterface</span><span class="token punctuation">;</span> <span class="token keyword">abstract</span> <span class="token keyword">class</span> <span class="token class-name">BaseRepository</span> <span class="token keyword">implements</span> <span class="token class-name">BaseRepositoryInterface</span> <span class="token punctuation">{</span> <span class="token comment">/** * @var IlluminateDatabaseEloquentModel */</span> <span class="token keyword">protected</span> <span class="token variable">$model</span><span class="token punctuation">;</span> <span class="token comment">/** * EloquentRepository constructor. */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">__construct</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 function">setModel</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">/** * get model * @return string */</span> <span class="token keyword">abstract</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">getModel</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/** * Set model */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">setModel</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">model</span> <span class="token operator">=</span> <span class="token function">app</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">make</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 function">getModel</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 comment">/** * Get All * @return IlluminateDatabaseEloquentCollection|static[] */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">getAll</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token variable">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token property">model</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">all</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">/** * Get one * @param $id * @return mixed */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">find</span><span class="token punctuation">(</span><span class="token variable">$id</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$result</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">model</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">find</span><span class="token punctuation">(</span><span class="token variable">$id</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token variable">$result</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Create * @param array $attributes * @return mixed */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">create</span><span class="token punctuation">(</span><span class="token keyword">array</span> <span class="token variable">$attributes</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token variable">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token property">model</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">create</span><span class="token punctuation">(</span><span class="token variable">$attributes</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Update * @param $id * @param array $attributes * @return bool|mixed */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">update</span><span class="token punctuation">(</span><span class="token variable">$id</span><span class="token punctuation">,</span> <span class="token keyword">array</span> <span class="token variable">$attributes</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$result</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 function">find</span><span class="token punctuation">(</span><span class="token variable">$id</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$result</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$result</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">update</span><span class="token punctuation">(</span><span class="token variable">$attributes</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token variable">$result</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Delete * * @param $id * @return bool */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">delete</span><span class="token punctuation">(</span><span class="token variable">$id</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$result</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 function">find</span><span class="token punctuation">(</span><span class="token variable">$id</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$result</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$result</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">delete</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token variable">$result</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> </span> |
- Tiếp theo mình sẽ tạo userRepository và viết lại function store để thêm dữ liệu thay vì dùng create
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | <span class="token keyword">use</span> <span class="token package">Auth</span><span class="token punctuation">;</span> <span class="token keyword">use</span> <span class="token package">App<span class="token punctuation"></span>Models<span class="token punctuation"></span>User</span><span class="token punctuation">;</span> <span class="token keyword">use</span> <span class="token package">App<span class="token punctuation"></span>Repositories<span class="token punctuation"></span>Eloquents<span class="token punctuation"></span>BaseRepository</span><span class="token punctuation">;</span> <span class="token keyword">use</span> <span class="token package">App<span class="token punctuation"></span>Repositories<span class="token punctuation"></span>Interfaces<span class="token punctuation"></span>UserRepositoryInterface</span><span class="token punctuation">;</span> <span class="token keyword">class</span> <span class="token class-name">UserRepository</span> <span class="token keyword">extends</span> <span class="token class-name">BaseRepository</span> <span class="token keyword">implements</span> <span class="token class-name">UserRepositoryInterface</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">getModel</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> User<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 keyword">public</span> <span class="token keyword">function</span> <span class="token function">store</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 keyword">if</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">hasFile</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'avatar'</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$path</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">file</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'avatar'</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">store</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'public/images'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token variable">$data</span><span class="token punctuation">[</span><span class="token single-quoted-string string">'avatar'</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">strstr</span><span class="token punctuation">(</span><span class="token variable">$path</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'/'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token variable">$data</span><span class="token punctuation">[</span><span class="token single-quoted-string string">'name'</span><span class="token punctuation">]</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 property">name</span><span class="token punctuation">;</span> <span class="token variable">$data</span><span class="token punctuation">[</span><span class="token single-quoted-string string">'email'</span><span class="token punctuation">]</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 property">email</span><span class="token punctuation">;</span> <span class="token variable">$data</span><span class="token punctuation">[</span><span class="token single-quoted-string string">'password'</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">bcrypt</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">password</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token variable">$data</span><span class="token punctuation">[</span><span class="token single-quoted-string string">'role'</span><span class="token punctuation">]</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 property">role</span><span class="token punctuation">;</span> <span class="token variable">$user</span> <span class="token operator">=</span> User<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">create</span><span class="token punctuation">(</span><span class="token variable">$data</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> |
Trên đây là việc tạo repository nếu các bạn chưa có kiến thức về repository trong laravel thì có thể tìm hiểu tại đây
2. Viết test cho UserRepository
Chúng ta sẽ tạo 1 file UserRepositoryTest để viết test
Chạy lệnh để tạo unittest:
php artisan make:test Repositories/UserRepositoryTest --unit
lệnh trên sẽ sinh ra một thư mục với đường dẫn là test/Unit/Repositories/UserRepositoryTest.php
file ban đầu sẽ như này:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <span class="token php language-php"><span class="token delimiter important"><?php</span> <span class="token keyword">namespace</span> <span class="token package">Tests<span class="token punctuation"></span>Unit<span class="token punctuation"></span>Repositories</span><span class="token punctuation">;</span> <span class="token keyword">use</span> <span class="token package">Tests<span class="token punctuation"></span>TestCase</span><span class="token punctuation">;</span> <span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation"></span>Foundation<span class="token punctuation"></span>Testing<span class="token punctuation"></span>WithFaker</span><span class="token punctuation">;</span> <span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation"></span>Foundation<span class="token punctuation"></span>Testing<span class="token punctuation"></span>RefreshDatabase</span><span class="token punctuation">;</span> <span class="token keyword">class</span> <span class="token class-name">UserRepositoryTest</span> <span class="token keyword">extends</span> <span class="token class-name">TestCase</span> <span class="token punctuation">{</span> <span class="token comment">/** * A basic unit test example. * * @return void */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">testExample</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 function">assertTrue</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> </span> |
Tiếp theo viết function testStore để test function store của UserRepository
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | <span class="token php language-php"><span class="token delimiter important"><?php</span> <span class="token keyword">namespace</span> <span class="token package">Tests<span class="token punctuation"></span>Unit<span class="token punctuation"></span>Repositories</span><span class="token punctuation">;</span> <span class="token keyword">use</span> <span class="token package">Tests<span class="token punctuation"></span>TestCase</span><span class="token punctuation">;</span> <span class="token keyword">use</span> <span class="token package">App<span class="token punctuation"></span>Models<span class="token punctuation"></span>User</span><span class="token punctuation">;</span> <span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation"></span>Http<span class="token punctuation"></span>UploadedFile</span><span class="token punctuation">;</span> <span class="token keyword">use</span> <span class="token package">App<span class="token punctuation"></span>Repositories<span class="token punctuation"></span>Eloquents<span class="token punctuation"></span>UserRepository</span><span class="token punctuation">;</span> <span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation"></span>Foundation<span class="token punctuation"></span>Testing<span class="token punctuation"></span>WithFaker</span><span class="token punctuation">;</span> <span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation"></span>Foundation<span class="token punctuation"></span>Testing<span class="token punctuation"></span>RefreshDatabase</span><span class="token punctuation">;</span> <span class="token keyword">class</span> <span class="token class-name">UserRepositoryTest</span> <span class="token keyword">extends</span> <span class="token class-name">TestCase</span> <span class="token punctuation">{</span> <span class="token comment">/** * test get model * * @return void */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">testGetModel</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$userRepository</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">UserRepository</span><span class="token punctuation">;</span> <span class="token variable">$data</span> <span class="token operator">=</span> <span class="token variable">$userRepository</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">getModel</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 function">assertEquals</span><span class="token punctuation">(</span>User<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token variable">$data</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * test store function model * * @return void */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">testStore</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$userRepository</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">UserRepository</span><span class="token punctuation">;</span> <span class="token variable">$params</span> <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token single-quoted-string string">'name'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token single-quoted-string string">'abc'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'email'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token single-quoted-string string">'<a href="/cdn-cgi/l/email-protection" class="__cf_email__">[email protected]</a>'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'password'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token single-quoted-string string">'12345678'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'role'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token single-quoted-string string">'1'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'avatar'</span> <span class="token operator">=</span><span class="token operator">></span> UploadedFile<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">fake</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">image</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'avatar.jpg'</span><span class="token punctuation">)</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 keyword">new</span> <span class="token class-name"><span class="token punctuation"></span>Illuminate<span class="token punctuation"></span>Http<span class="token punctuation"></span>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 function">replace</span><span class="token punctuation">(</span><span class="token variable">$params</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token variable">$result</span> <span class="token operator">=</span> <span class="token variable">$userRepository</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">store</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 variable">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">assertEquals</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> User<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">all</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">count</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> |
Vì mình dùng model User,UseRepository,uploaderFile nên mình sẽ use nó vào
1 2 3 4 | use AppModelsUser; use IlluminateHttpUploadedFile; use AppRepositoriesEloquentsUserRepository; |
Trên có hai hàm là testGetModel để test get model và testStore để test store của UserRepository
Trong function testStore ta sẽ tạo dữ liệu và gọi hàm store của userRepository để thêm dữ liệu$result = $userRepository->store($request);
Sau đó ta kiểm tra xem dữ liệu đã được thêm hay chưa$this->assertEquals(1, User::all()->count());
câu lệnh trên sẽ trả về true nếu thêm dữ liệu thành công
vậy là xong . sau đó chúng ta chạy lệnh để test:
vendor/bin/phpunit
Các bạn làm tương tự với các chức năng show, update, destroy nhé.
Tổng kết
Trên đây là những kiến thức cơ bản về test Repository laravel, có góp ý gì vui lòng comment vào vài viết nhé. Thanks