Injeksi tiruan secara otomatis ke subjek pengujian melalui anotasi #InjectMocks dan #Mock, untuk mempercepat pengujian unit dengan PHPUnit.
Leia versi portugis di sini.
Untuk menginstal di lingkungan pengembangan:
composer require --dev silasyudi/inject-mocks
Dengan menggunakan anotasi #InjectMocks dan #Mock di kelas pengujian, Anda dapat secara otomatis memasukkan tiruan ke dalam subjek pengujian.
Dalam skenario umum, kami akan melakukannya seperti ini:
class SomeTest extends PHPUnit Framework TestCase
{
public void testSomething()
{
$ someDependency = $ this -> createMock (Dependency::class);
$ anotherDependency = $ this -> createMock (AnotherDependency::class);
. . .
$ subject = new Service ( $ someDependency , $ anotherDependency , ...);
. . .
}
...
Pendekatan ini menimbulkan kesulitan dalam pemeliharaan, karena jika subjek pengujian diubah, baik dengan menambah, mengurangi, atau mengganti dependensi, Anda harus mengubahnya di setiap pengujian.
Dengan anotasi #InjectMocks/#Mock, kami mengabstraksi perubahan subjek tes ini. Contoh:
use SilasYudi InjectMocks InjectMocks ;
use SilasYudi InjectMocks Mock ;
use SilasYudi InjectMocks MockInjector ;
class SomeTest extends PHPUnit Framework TestCase
{
#[Mock]
private Dependency $ someDependency ;
#[Mock]
private AnotherDependency $ anotherDependency ;
. . .
# [InjectMocks]
public function setUp() : void
{
MockInjector:: inject ( $ this );
}
public void testSomething ()
{
// $this->subject e as dependências já estão instanciadas.
}
...
Seperti pada contoh pada topik sebelumnya, atribut #InjectMocks harus ditempatkan pada properti subjek tes yang ingin Anda uji, dan atribut #Mock harus ditempatkan pada properti yang sesuai dengan dependensi yang ingin Anda tiru atau menyuntikkan.
Setelah itu jalankan service injector dengan kalimat MockInjector::inject($this)
. Eksekusi ini dapat dideklarasikan di setiap pengujian atau di setUp
.
Setelah menjalankan injektor, service
yang dianotasi dengan #InjectMocks akan menjadi instance nyata yang tersedia dalam lingkup kelas pengujian, dan setiap dependensi yang dianotasi dengan #Mock akan menjadi instance MockObject, disuntikkan ke subjek pengujian melalui konstruktor, dan akan juga tersedia dalam lingkup kelas tes.
MockInjectException
.#InjectMocks dan #Mock bekerja secara mandiri dan sendiri, atau bersama-sama. Detail tentang masing-masing:
Ini akan membuat instance nyata melalui konstruktor, dan jika ada parameter di konstruktor, nilai berikut akan digunakan di setiap parameter, dalam urutan ini:
mock
yang dibuat dari atribut #[Mock], jika ada;default
jika merupakan parameter opsional;null
jika diketik sebagai null
;mock
jika itu bukan tipe primitif. Dalam hal ini, mock
ini tidak akan dimasukkan ke dalam lingkup TestCase;MockInjectException
akan muncul.Catatan: Anda dapat menggunakan atribut #Mock pada semua, beberapa, atau tidak sama sekali dependensi subjek tes.
Akan membuat mock
yang dimasukkan ke dalam lingkup TestCase, tanpa menggunakan konstruktor. Perilaku pembuatan ini identik dengan TestCase::createMock()
.