Perpustakaan untuk menanggalkan dan menetapkan harapan pada permintaan HTTP di Delphi dengan Dunitx.
* Webmocks dikembangkan di Delphi 10.3 (RIO) dan 10.4 (Sydney) dan sampai versi 3.0 kompatibel kembali ke XE8. Karena webmock memanfaatkan System.Net Library yang diperkenalkan dengan Xe8 tidak akan kompatibel dengan versi sebelumnya. Jika Anda memerlukan menginstal pada versi Delphi sebelum 10.3 Anda harus menginstal versi 2.0.0.
WebMocks 3.2.0 tersedia melalui manajer paket Embarcadero untuk Delphi Getit. Jika Anda memiliki versi Delphi terbaru termasuk getit maka ini harus menjadi metode instalasi yang disukai.
Webmocks sekarang harus terdaftar di Delphinus Package Manager.
Pastikan untuk memulai kembali Delphi setelah menginstal melalui Delphinus jika tidak unit tidak dapat ditemukan di proyek pengujian Anda.
Source yang diekstraksi ke "jalur perpustakaan" dan "jalur penjelajahan". Jika Anda ingin pengantar yang lembut untuk webmocks untuk Delphi, ada serangkaian artikel yang diterbitkan di Dev dimulai dengan pengujian klien HTTP di Delphi dengan Dunitx dan Webmocks.
Delphi-Webmocks-Demos berisi serangkaian demonstrasi untuk menyertai artikel.
Versi 2 telah menjatuhkan Delphi. Namespace dari semua unit. Peningkatan proyek apa pun ke versi 2 atau yang lebih baru perlu menjatuhkan Delphi. Awalan dari unit webmocks yang disertakan.
Di diperlukan file unit uji Anda, beberapa langkah sederhana diperlukan.
WebMock ke antarmuka Anda uses .TestFixture Anda menggunakan Setup dan TearDown untuk membuat/menghancurkan instance TWebMock . unit MyTestObjectTests;
interface
uses
DUnitX.TestFramework,
MyObjectUnit,
WebMock;
type
TMyObjectTests = class (TObject)
private
WebMock: TWebMock;
Subject: TMyObject;
public
[Setup]
procedure Setup ;
[TearDown]
procedure TearDown ;
[Test]
procedure TestGet ;
end ;
implementation
procedure TMyObjectTests.Setup ;
begin
WebMock := TWebMock.Create;
end ;
procedure TMyObjectTests.TearDown ;
begin
WebMock.Free;
end ;
procedure TMyObjectTests.TestGet ;
begin
// Arrange
// Stub the request
WebMock.StubRequest( ' GET ' , ' /endpoint ' );
// Create your subject and point it at the endpoint
Subject := TMyObject.Create;
Subject.EndpointURL := WebMock.URLFor( ' endpoint ' );
// Act
Subject.Get;
// Assert: check your subject behaved correctly
Assert.IsTrue(Subject.ReceivedResponse);
end ;
initialization
TDUnitX.RegisterTestFixture(TMyObjectTests);
end . Secara default TWebMock akan mengikat ke port yang ditugaskan secara dinamis mulai dari 8080 . Perilaku ini dapat ditimpa dengan menentukan port saat pembuatan.
WebMock := TWebMock.Create( 8088 ); Penggunaan fungsi WebMock.URLFor dalam tes Anda adalah untuk menyederhanakan pembangunan URL yang valid. Properti Port berisi port terikat saat ini dan properti BaseURL berisi URL yang valid untuk root server.
Bentuk paling sederhana dari pencocokan permintaan dan titik awal untuk semua stub permintaan adalah dengan metode HTTP dan jalur dokumen. Misalnya mematahkan kata kerja GET ke root server / dicapai oleh:
WebMock.StubRequest( ' GET ' , ' / ' ); Penggunaan karakter kartu liar tunggal * dapat digunakan untuk mencocokkan permintaan apa pun . Misalnya, untuk mencocokkan semua permintaan POST terlepas dari jalur dokumen yang dapat Anda gunakan:
WebMock.StubRequest( ' POST ' , ' * ' );Demikian pula, untuk mencocokkan metode HTTP apa pun untuk jalur tertentu yang dapat Anda gunakan:
WebMock.StubRequest( ' * ' , ' /path ' ); Sangat mungkin untuk memiliki tangkapan-semua * dan * untuk metode HTTP dan jalur dokumen.
Header permintaan HTTP dapat dicocokkan seperti:
WebMock.StubRequest( ' * ' , ' * ' ).WithHeader( ' Name ' , ' Value ' ); Cocokkan banyak header dapat dicapai dalam 2 cara. Yang pertama adalah hanya berantai WithHeader panggilan misalnya:
WebMock.StubRequest( ' * ' , ' * ' )
.WithHeader( ' Header-1 ' , ' Value-1 ' )
.WithHeader( ' Header-2 ' , ' Value-2 ' ); Atau, WithHeaders menerima TStringList dari pasangan nilai kunci misalnya:
var
Headers: TStringList;
begin
Headers := TStringList.Create;
Headers.Values[ ' Header-1 ' ] := ' Value-1 ' ;
Headers.Values[ ' Header-2 ' ] := ' Value-2 ' ;
WebMock.StubRequest( ' * ' , ' * ' ).WithHeaders(Headers);
end ;Permintaan HTTP dapat dicocokkan dengan konten seperti:
WebMock.StubRequest( ' * ' , ' * ' ).WithBody( ' String content. ' ); Permintaan HTTP dapat dicocokkan dengan data formulir seperti yang dikirimkan dengan content-type application/x-www-form-urlencoded . Beberapa nilai bidang pencocokan dapat digabungkan. Misalnya:
WebMock.StubRequest( ' * ' , ' * ' )
.WithFormData( ' AField ' , ' A value. ' )
.WithFormData( ' AOtherField ' , ' Another value. ' ); Untuk hanya mencocokkan keberadaan lapangan, wildcard * dapat diteruskan untuk nilai.
CATATAN: Anda tidak dapat mencocokkan data formulir ( WithFormData ) dan kandungan tubuh ( WithBody ) secara bersamaan. Menentukan keduanya akan menghasilkan panggilan terbaru yang menimpa pencocokan sebelumnya.
Pencocokan permintaan dengan ekspresi reguler dapat berguna untuk mematahkan rute dinamis untuk sumber daya yang tenang yang melibatkan nama sumber daya dan ID sumber daya yang tidak diketahui seperti /resource/999 . Permintaan seperti itu bisa ditangguhkan oleh:
WebMock.StubRequest( ' GET ' , TRegEx.Create( ' ^/resource/d+$ ' ));Header yang cocok dapat sama dengan dicapai dengan:
WebMock.StubRequest( ' * ' , ' * ' )
.WithHeader( ' Accept ' , TRegEx.Create( ' video/.+ ' ));Konten yang cocok dapat dilakukan seperti:
WebMock.StubRequest( ' * ' , ' * ' )
.WithBody(TRegEx.Create( ' Hello ' ));Konten data formulir yang cocok dapat dilakukan seperti:
WebMock.StubRequest( ' * ' , ' * ' )
.WithFormData( ' AField ' , TRegEx.Create( ' .* ' )); Catatan: Pastikan untuk menambahkan System.RegularExpressions ke klausa Penggunaan Anda.
Permintaan HTTP dapat dicocokkan dengan data JSON seperti yang dikirimkan dengan content-type application/json menggunakan WithJSON . Beberapa nilai bidang pencocokan dapat digabungkan. Misalnya:
WebMock.StubRequest( ' * ' , ' * ' )
.WithJSON( ' ABoolean ' , True)
.WithJSON( ' AFloat ' , 0.123 )
.WithJSON( ' AInteger ' , 1 )
.WithJSON( ' AString ' , ' value ' ); Argumen pertama bisa menjadi jalan. Misalnya, dalam JSON berikut, objects[0].key akan cocok dengan value 1 .
{
"objects" : [
{ "key" : " value 1 " },
{ "key" : " value 2 " }
]
}Catatan: Pola string dapat dicocokkan dengan melewati ekspresi reguler sebagai argumen kedua. Misalnya:
WebMock.StubRequest( ' * ' , ' * ' )
.WithJSON( ' objects[0].key ' , TRegEx.Create( ' valuesd+ ' ));Permintaan HTTP dapat dicocokkan dengan nilai data XML yang dikirimkan. Misalnya:
WebMock.StubRequest( ' * ' , ' * ' )
.WithXML( ' /Object/Attr1 ' , ' Value 1 ' );Argumen pertama adalah ekspresi XPath. Contoh sebelumnya akan membuat kecocokan positif dengan dokumen berikut:
<? xml version = " 1.0 " encoding = " UTF-8 " ?>
< Object >
< Attr1 >Value 1</ Attr1 >
</ Object >Argumen kedua dapat berupa nilai boolean, floating point, integer, atau string.
Jika logika pencocokan harus lebih kompleks daripada pencocokan sederhana, fungsi predikat dapat disediakan dalam tes untuk memungkinkan inspeksi/logika khusus untuk mencocokkan permintaan. Fungsi predikat anonim akan menerima objek IWebMockHTTPRequest untuk memeriksa permintaan. Jika fungsi predikat mengembalikan True maka rintisan akan dianggap sebagai kecocokan, jika kembali False itu tidak akan dicocokkan.
Contoh rintisan dengan fungsi predikat:
WebMock.StubRequest(
function(ARequest: IWebMockHTTPRequest): Boolean
begin
Result := True; // Return False to ignore request.
end
); Secara default, status respons akan menjadi 200 OK untuk permintaan yang mematikan. Jika permintaan dibuat ke TWebMock tanpa rintisan terdaftar, itu akan merespons 501 Not Implemented . Untuk menentukan status respons, gunakan ToRespond .
WebMock.StubRequest( ' GET ' , ' / ' ).ToRespond(TWebMockResponseStatus.NotFound);Header dapat ditambahkan ke rintisan respons seperti:
WebMock.StubRequest( ' * ' , ' * ' )
.ToRespond.WithHeader( ' Header-1 ' , ' Value-1 ' ); Seperti halnya header permintaan yang cocok dengan beberapa header dapat ditentukan baik melalui rantai metode atau dengan menggunakan metode WithHeaders .
WebMock.StubRequest( ' * ' , ' * ' ).ToRespond
.WithHeader( ' Header-1 ' , ' Value-1 ' )
.WithHeader( ' Header-2 ' , ' Value-2 ' );
/* or */
var
Headers: TStringList;
begin
Headers := TStringList.Create;
Headers.Values[ ' Header-1 ' ] := ' Value-1 ' ;
Headers.Values[ ' Header-2 ' ] := ' Value-2 ' ;
WebMock.StubRequest( ' * ' , ' * ' )
.ToRespond.WithHeaders(Headers);
end ; Secara default, respons yang tertipu mengembalikan bodi panjang nol dengan text/plain tipe konten. Konten respons sederhana yang mudah direpresentasikan sebagai string dapat diatur dengan WithBody .
WebMock.StubRequest( ' GET ' , ' / ' )
.ToRespond.WithBody( ' Text To Return ' );Jika Anda ingin mengembalikan tipe konten tertentu, dapat ditentukan sebagai argumen kedua misalnya
WebMock.StubRequest( ' GET ' , ' / ' )
.ToRespond.WithBody( ' { "status": "ok" } ' , ' application/json ' ); Saat menanggalkan tanggapan dengan konten biner atau besar, kemungkinan lebih mudah untuk menyediakan konten sebagai file. Ini dapat dicapai dengan menggunakan WithBodyFile yang memiliki tanda tangan yang sama seperti WithBody tetapi argumen pertama adalah jalur ke file.
WebMock.StubRequest( ' GET ' , ' / ' ).WithBodyFile( ' image.jpg ' ); Delphi-Webmocks akan mencoba untuk mengatur tipe konten sesuai dengan ekstensi file. Jika jenis file tidak diketahui maka tipe konten akan default ke application/octet-stream . Tipe konten dapat ditimpa dengan argumen kedua. misalnya
WebMock.StubRequest( ' GET ' , ' / ' ).WithBodyFile( ' file.myext ' , ' application/xml ' ); Catatan: Satu "gotcha" mengakses file dalam pengujian adalah lokasi file akan relatif terhadap pengujian yang dapat dieksekusi yang, secara default, menggunakan kompiler Windows 32-bit akan output ke folder Win32Debug . Untuk merujuk dengan benar file bernama Content.txt di folder proyek, jalurnya akan ....Content.txt .
Terkadang berguna untuk menanggapi permintaan secara dinamis. Misalnya:
WebMock.StubRequest( ' * ' , ' * ' )
.ToRespondWith(
procedure ( const ARequest: IWebMockHTTPRequest;
const AResponse: IWebMockResponseBuilder)
begin
AReponse
.WithStatus( 202 )
.WithHeader( ' header-1 ' , ' a-value ' )
.WithBody( ' Some content... ' );
end
);Ini memungkinkan pengujian fitur yang memerlukan inspeksi permintaan yang lebih dalam atau untuk mencerminkan nilai dari permintaan kembali dalam respons. Misalnya:
WebMock.StubRequest( ' GET ' , ' /echo_header ' )
.ToRespondWith(
procedure ( const ARequest: IWebMockHTTPRequest;
const AResponse: IWebMockHTTPResponseBuilder)
begin
AResponse.WithHeader( ' my-header ' , ARequest.Headers.Values[ ' my-header ' ]);
end
);Ini juga dapat berguna untuk mensimulasikan kegagalan untuk sejumlah upaya sebelum kembali sukses. Misalnya:
var LRequestCount := 0 ;
WebMock.StubRequest( ' GET ' , ' /busy_endpoint ' )
.ToRespondWith(
procedure ( const ARequest: IWebMockHTTPRequest;
const AResponse: IWebMockHTTPResponseBuilder)
begin
Inc(LRequestCount);
if LRequestCount < 3 then
AResponse.WithStatus( 408 , ' Request Timeout ' )
else
AResponse.WithStatus( 200 , ' OK ' );
end
); Jika Anda perlu menghapus rintisan terdaftar saat ini, Anda dapat memanggil ResetStubRegistry atau Reset pada instance twebmock. Metode Reset umum akan mengembalikan instance twebmock ke negara kosong termasuk mengosongkan registri stub. ResetStubRegistry yang lebih spesifik akan seperti yang disarankan dengan jelas hanya Registry Stub.
Masing -masing dan setiap permintaan yang dibuat dari instance twebmock dicatat di properti History . Entri riwayat berisi semua informasi permintaan web utama: metode; Permintaan; Header; dan tubuh.
Dimungkinkan untuk menulis pernyataan berdasarkan riwayat permintaan misalnya:
WebClient.Get(WebMock.URLFor( ' document ' ));
Assert.AreEqual( ' GET ' , WebMock.History.Last.Method);
Assert.AreEqual( ' /document ' , WebMock.History.Last.RequestURI);Catatan: Jika Anda menemukan diri Anda menulis pernyataan di manor ini, Anda harus melihat pernyataan permintaan yang memberikan cara yang lebih ringkas untuk mendefinisikan pernyataan ini.
Jika Anda perlu menghapus riwayat permintaan, Anda dapat memanggil ResetHistory atau Reset pada contoh twebmock. Metode Reset umum akan mengembalikan instance twebmock ke keadaan kosong termasuk mengosongkan sejarah. ResetHistory yang lebih spesifik akan disarankan hanya dengan jelas sejarah.
Selain menggunakan pernyataan Dunitx untuk memvalidasi kode Anda yang berperilaku seperti yang diharapkan, Anda juga dapat menggunakan pernyataan permintaan untuk memeriksa apakah permintaan Anda mengharapkan kode Anda melakukan di mana dieksekusi seperti yang diharapkan.
Pernyataan Permintaan Sederhana:
WebClient.Get(WebMock.URLFor( ' / ' ));
WebMock.Assert.Get( ' / ' ).WasRequested; // Passes Seperti halnya permintaan, Anda dapat mencocokkan permintaan dengan metode HTTP, URI, parameter kueri, header, dan konten tubuh (termasuk WithJSON dan WithXML ).
WebMock.Assert
.Patch( ' /resource`)
.WithQueryParam( ' ParamName ' , ' Value ' )
.WithHeader( ' Content- Type ' , ' application/json ' )
.WithBody( ' { "resource": { "propertyA": "Value" } } ' )
.WasRequested; Apa pun yang dapat ditegaskan secara positif ( WasRequested ) juga dapat ditegaskan secara negatif dengan WasNotRequested . Ini berguna untuk memeriksa kode Anda tidak melakukan permintaan tambahan yang tidak diinginkan.
Proyek ini mengikuti versi semantik.
Hak Cipta © 2019-2024 Richard Hatherall [email protected]
Webmocks didistribusikan berdasarkan ketentuan lisensi Apache (versi 2.0).
Lihat lisensi untuk detailnya.