Saya memiliki pengontrol di C # menggunakan kerangka ASP.Net MVC
public class HomeController:Controller{
public ActionResult Index()
{
if (Request.IsAjaxRequest())
{
//do some ajaxy stuff
}
return View("Index");
}
}
Saya mendapat beberapa tip tentang mengejek dan berharap untuk menguji kode dengan yang berikut dan RhinoMocks
var mocks = new MockRepository();
var mockedhttpContext = mocks.DynamicMock<HttpContextBase>();
var mockedHttpRequest = mocks.DynamicMock<HttpRequestBase>();
SetupResult.For(mockedhttpContext.Request).Return(mockedHttpRequest);
var controller = new HomeController();
controller.ControllerContext = new ControllerContext(mockedhttpContext, new RouteData(), controller);
var result = controller.Index() as ViewResult;
Assert.AreEqual("About", result.ViewName);
Namun saya terus mendapatkan kesalahan ini:
Exception System.ArgumentNullException: System.ArgumentNullException: Nilai tidak boleh nol. Nama parameter: permintaan di System.Web.Mvc.AjaxRequestExtensions.IsAjaxRequest (permintaan HttpRequestBase)
Karena Request
objek pada pengontrol tidak memiliki setter. Saya mencoba agar tes ini berfungsi dengan baik dengan menggunakan kode yang disarankan dari jawaban di bawah ini.
Ini menggunakan Moq alih-alih RhinoMocks, dan dalam menggunakan Moq saya menggunakan yang berikut untuk tes yang sama:
var request = new Mock<HttpRequestBase>();
// Not working - IsAjaxRequest() is static extension method and cannot be mocked
// request.Setup(x => x.IsAjaxRequest()).Returns(true /* or false */);
// use this
request.SetupGet(x => x.Headers["X-Requested-With"]).Returns("XMLHttpRequest");
var context = new Mock<HttpContextBase>();
context.SetupGet(x => x.Request).Returns(request.Object);
var controller = new HomeController(Repository, LoginInfoProvider);
controller.ControllerContext = new ControllerContext(context.Object, new RouteData(), controller);
var result = controller.Index() as ViewResult;
Assert.AreEqual("About", result.ViewName);
tetapi dapatkan kesalahan berikut:
Exception System.ArgumentException: System.ArgumentException: Penyiapan yang tidak valid pada anggota yang tidak dapat ditimpa: x => x.Headers ["X-Diminta-Dengan"] di Moq.Mock.ThrowIfCantOverride (Penyiapan Ekspresi, penyiapan Metode, MetodeInfo metodeInfo)
Sekali lagi, sepertinya saya tidak bisa mengatur header permintaan. Bagaimana cara menetapkan nilai ini, dalam RhinoMocks atau Moq?
Jawaban:
Menggunakan Moq :
DIPERBARUI:
Mengejek
Request.Headers["X-Requested-With"]
atauRequest["X-Requested-With"]
bukannyaRequest.IsAjaxRequest()
.sumber
Bagi siapa pun yang menggunakan NSubstitute, saya dapat mengubah jawaban di atas dan melakukan sesuatu seperti ini ... (di mana Detail adalah nama metode Action pada controller)
sumber
Ini adalah solusi yang berfungsi menggunakan RhinoMocks. Saya telah mendasarkannya pada solusi Moq yang saya temukan di http://thegrayzone.co.uk/blog/2010/03/mocking-request-isajaxrequest/
sumber
Is AjaxRequest adalah metode ekstensi. Jadi Anda bisa melakukannya dengan cara berikut menggunakan Rhino:
sumber
Sepertinya Anda mencari ini,
Penggunaan dalam Kontroler:
sumber
Anda perlu mengejek HttpContextBase dan memasukkannya ke properti ControllerContext Anda, seperti itu:
sumber
Untuk membuat
IsAjaxRequest()
kesalahan kembali selama pengujian Unit, Anda perlu mengatur Header Permintaan serta nilai pengumpulan permintaan baik dalam metode pengujian Anda seperti yang diberikan di bawah ini:Alasan pengaturan keduanya tersembunyi dalam implementasi IsAjaxRequest () yang diberikan di bawah ini:
Ia menggunakan kedua Koleksi permintaan dan tajuk ini sebabnya kami perlu membuat pengaturan untuk Koleksi Header dan Permintaan.
ini akan membuat permintaan untuk mengembalikan false ketika itu bukan permintaan ajax. untuk mengembalikannya, Anda dapat melakukan hal berikut:
sumber
Saya menemukan cara lain untuk menambahkan objek HttpRequestMessage ke dalam permintaan Anda selama API Web sebagai berikut
sumber
(Agak terlambat ke pesta tapi aku pergi untuk rute yang berbeda jadi kupikir aku akan berbagi)
Untuk menggunakan kode murni / cara mengejek pengujian ini tanpa membuat tiruan untuk kelas Http saya menerapkan IControllerHelper yang memiliki metode Inisialisasi yang mengambil Permintaan sebagai parameter dan kemudian membuka properti yang saya inginkan misalnya:
Kemudian di pengontrol saya, saya sebut inisialisasi pada awal metode:
Dan kemudian kode saya hanya bergantung pada dependensi yang dapat diejek.
Untuk tes fungsional, saya hanya mengganti iControllerHelper dalam komposisi sebagai pengganti.
sumber