Saya memiliki layanan web yang saya coba uji unit. Dalam layanan itu menarik beberapa nilai dari HttpContext
seperti ini:
m_password = (string)HttpContext.Current.Session["CustomerId"];
m_userID = (string)HttpContext.Current.Session["CustomerUrl"];
dalam tes unit saya membuat konteks menggunakan permintaan pekerja sederhana, seperti:
SimpleWorkerRequest request = new SimpleWorkerRequest("", "", "", null, new StringWriter());
HttpContext context = new HttpContext(request);
HttpContext.Current = context;
Namun, setiap kali saya mencoba mengatur nilai HttpContext.Current.Session
HttpContext.Current.Session["CustomerId"] = "customer1";
HttpContext.Current.Session["CustomerUrl"] = "customer1Url";
Saya mendapatkan pengecualian referensi nol yang mengatakan HttpContext.Current.Session
nol.
Apakah ada cara untuk menginisialisasi sesi saat ini dalam unit test?
Jawaban:
Kami harus mengejek
HttpContext
dengan menggunakanHttpContextManager
dan memanggil pabrik dari dalam aplikasi kami serta Tes UnitAnda kemudian akan mengganti semua panggilan
HttpContext.Current
denganHttpContextManager.Current
dan memiliki akses ke metode yang sama. Kemudian ketika Anda menguji, Anda juga dapat mengaksesHttpContextManager
dan mengejek harapan AndaIni adalah contoh menggunakan Moq :
dan kemudian menggunakannya dalam pengujian unit Anda, saya menyebutnya dalam metode Test Init saya
Anda kemudian dapat, dalam metode di atas menambahkan hasil yang diharapkan dari Sesi yang Anda harapkan tersedia untuk layanan web Anda.
sumber
HttpContextManager
akan menjadi nama yang lebih baik daripadaHttpContextSource
tetapi saya setujuHttpContextFactory
menyesatkan.Anda dapat "memalsukannya" dengan membuat yang baru
HttpContext
seperti ini:http://www.necronet.org/archive/2010/07/28/unit-testing-code-that-uses-httpcontext-current-session.aspx
Saya telah mengambil kode itu dan menaruhnya di kelas pembantu statis seperti:
Atau alih-alih menggunakan refleksi untuk membuat
HttpSessionState
instance baru , Anda bisa menempelkan AndaHttpSessionStateContainer
keHttpContext
(sesuai komentar Brent M. Spell):dan kemudian Anda bisa menyebutnya di unit test Anda seperti:
sumber
Server.MapPath()
tidak akan berfungsi jika Anda menggunakan ini juga.Solusi Milox lebih baik daripada yang diterima IMHO tapi saya punya beberapa masalah dengan implementasi ini ketika menangani url dengan querystring .
Saya membuat beberapa perubahan agar berfungsi dengan baik dengan url apa pun dan untuk menghindari Refleksi.
sumber
httpContext.Session
, ada ide bagaimana melakukan hal yang samahttpContext.Application
?Saya mengalami sesuatu tentang ini beberapa waktu lalu.
Unit Pengujian HttpContext.Current.Session di MVC3 .NET
Semoga ini bisa membantu.
sumber
Jika Anda menggunakan kerangka kerja MVC, ini harusnya berfungsi. Saya menggunakan Milox's FakeHttpContext dan menambahkan beberapa baris kode tambahan. Idenya datang dari pos ini:
http://codepaste.net/p269t8
Ini sepertinya berfungsi di MVC 5. Saya belum mencoba ini di versi MVC sebelumnya.
sumber
Anda dapat mencoba FakeHttpContext :
sumber
Di asp.net Core / MVC 6 rc2 Anda dapat mengatur
HttpContext
rc 1 tadinya
https://stackoverflow.com/a/34022964/516748
Pertimbangkan untuk menggunakan
Moq
sumber
Jawaban yang bekerja dengan saya adalah apa yang telah ditulis @Anthony, tetapi Anda harus menambahkan baris lain yang mana
jadi kamu bisa menggunakan ini:
sumber
Coba ini:
Dan Tambahkan kelas:
Ini akan memungkinkan Anda untuk menguji dengan sesi dan cache.
sumber
Saya mencari sesuatu yang kurang invasif daripada opsi yang disebutkan di atas. Pada akhirnya saya datang dengan solusi murahan, tetapi mungkin membuat beberapa orang bergerak sedikit lebih cepat.
Pertama saya membuat kelas TestSession :
Kemudian saya menambahkan parameter opsional ke konstruktor pengendali saya. Jika parameter ada, gunakan untuk manipulasi sesi. Jika tidak, gunakan HttpContext.Session:
Sekarang saya bisa menyuntikkan TestSession saya ke controller:
sumber
Tidak pernah mengejek .. tidak pernah! Solusinya cukup sederhana. Mengapa memalsukan ciptaan yang begitu indah
HttpContext
?Dorong sesi ke bawah! (Hanya baris ini sudah cukup bagi kebanyakan dari kita untuk mengerti tetapi dijelaskan secara rinci di bawah)
(string)HttpContext.Current.Session["CustomerId"];
adalah bagaimana kita mengaksesnya sekarang. Ubah ini menjadiSaat dipanggil dari pengujian, _customObject menggunakan toko alternatif (nilai DB atau kunci cloud [ http://www.kvstore.io/] )
Tetapi ketika dipanggil dari aplikasi nyata,
_customObject
menggunakanSession
.bagaimana ini dilakukan? yah ... Injeksi Ketergantungan!
Jadi tes dapat mengatur sesi (bawah tanah) dan kemudian memanggil metode aplikasi seolah-olah tidak tahu apa-apa tentang sesi. Kemudian uji diam-diam memeriksa apakah kode aplikasi dengan benar memperbarui sesi. Atau jika aplikasi berperilaku berdasarkan nilai sesi yang ditetapkan oleh tes.
Sebenarnya, kami akhirnya mengejek meskipun aku berkata: "tidak pernah mengejek". Karena kami tidak bisa membantu tetapi tergelincir ke aturan berikutnya, "mengejek di tempat yang paling menyakitkan!". Mengejek besar
HttpContext
atau mengejek sesi kecil, yang paling tidak menyakitkan? jangan tanya saya dari mana aturan ini berasal. Mari kita katakan akal sehat saja. Ini adalah bacaan yang menarik tentang tidak mengejek karena unit test dapat membunuh kitasumber
Jawaban @Ro Hit memberi banyak membantu saya, tetapi saya kehilangan kredensial pengguna karena saya harus memalsukan pengguna untuk pengujian unit otentikasi. Karena itu, izinkan saya menjelaskan bagaimana saya menyelesaikannya.
Menurut ini , jika Anda menambahkan metode
dan kemudian tambahkan
ke baris terakhir dari
TestSetup
metode yang Anda lakukan, kredensial pengguna ditambahkan dan siap digunakan untuk pengujian otentikasi.Saya juga memperhatikan bahwa ada bagian lain dalam HttpContext yang mungkin Anda butuhkan, seperti
.MapPath()
metode. Ada FakeHttpContext yang tersedia, yang dijelaskan di sini dan dapat diinstal melalui NuGet.sumber
Saya menemukan solusi sederhana berikut untuk menentukan pengguna di HttpContext: https://forums.asp.net/post/5828182.aspx
sumber
Coba dengan cara ini ..
sumber