ASP.NET pengujian unit WebApi dengan Request.CreateResponse

147

Saya mencoba menulis beberapa tes unit untuk ApiController saya dan menghadapi beberapa masalah. Ada metode ekstensi yang bagus yang disebut Request.CreateResponse yang banyak membantu dalam menghasilkan respons.

public HttpResponseMessage Post(Product product)
{
  var createdProduct = repo.Add(product);
  return this.Request.CreateResponse(HttpStatusCode.Created, createdProduct);
}

Apakah ada cara untuk mengejek CreateResponse tanpa menggunakan tiruan parsial atau penggunaan langsung "new HttpResponseMessage (...)"?

sebagai
sumber
1
Mengapa Anda ingin mengejeknya CreateResponse? Mengapa tidak menegaskan kembali HttpResponseMessage Contentdan StatusCodeproperti bahwa nilai yang benar diatur?
nemesv
3
Jika saya menjalankan metode ini dari unit test, itu akan gagal dengan pengecualian konfigurasi tidak diatur.
asa
1
Ok, malu pada saya, saya hanya perlu untuk menulis this.Request.CreateResponse (HttpStatusCode.Accepted, createdProduct, GlobalConfiguration.Configuration)
asa

Jawaban:

243

Cara lain untuk menyelesaikan ini adalah dengan melakukan hal berikut:

controller.Request = new HttpRequestMessage();
controller.Request.Properties.Add(HttpPropertyKeys.HttpConfigurationKey, 
                                  new HttpConfiguration());

Jika Anda memutakhirkan ke webapi 5.0, maka Anda harus mengubahnya ke:

controller.Request = new HttpRequestMessage();
controller.Request.SetConfiguration(new HttpConfiguration());

Alasan mengapa Anda perlu melakukan ini adalah karena Anda harus Requestmengisi pada controller jika tidak metode ekstensi Requesttidak akan berfungsi. Anda juga harus memiliki HttpConfigurationset pada Permintaan jika tidak routing dan bagian lain dari pipa tidak akan berfungsi dengan benar.

jonnii
sumber
Ya, itu mungkin bekerja juga, tetapi tampaknya Request.CreateResponse juga berfungsi.
asa
4
Menambahkan GlobalConfiguration.Configuration masih membuat null. Menyetel Permintaan berhasil untuk saya, namun ini bukan akhir dari masalah saya karena Tindakan saya juga memanggil Url.Link dan nama rute tidak ditentukan.
foolshat
Bantuan untuk mengatur rute stackoverflow.com/questions/11779311/...
foolshat
Mengatur ControllerContext setelah panggilan ini memberi saya kesalahan itu juga, tetapi hanya dengan WebApi 5.0.0. Tetapi jika saya menetapkan objek HttpConfiguration pada Request yang terakhir , itu berfungsi dengan baik.
mikebridge
Ini berfungsi dengan baik, tetapi saya gagal memahami mengapa ini berhasil. Bisakah Anda menjelaskan hal ini dalam jawabannya?
Jan_V
24

Anda bisa mengatur objek pengontrol untuk testabilitas seperti ini:

var config = new HttpConfiguration();
var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/api/products");
var route = config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{id}");
var routeData = new HttpRouteData(route, new HttpRouteValueDictionary { { "controller", "products" } });

controller.ControllerContext = new HttpControllerContext(config, routeData, request);
controller.Request = request;
controller.Request.Properties[HttpPropertyKeys.HttpConfigurationKey] = config;

Disalin dari posting blog komprehensif Peter Provost di Unit Testing ASP.NET Web API .

mono68
sumber
1
Anda mungkin juga tertarik dengan dokumen MS yang terkait dengan ini: docs.microsoft.com/en-us/aspnet/web-api/overview/… Anda juga mungkin perlu menambahkan referensi ke System.Web.Http dan System.Net. Http
Aaron Hoffman
4

Untuk Web API 2, Anda cukup menambahkan

controller.Request = new HttpRequestMessage();
controller.Configuration = new HttpConfiguration();

Seperti itu

[TestMethod]
public void GetReturnsProduct()
{
    // Arrange
    var controller = new ProductsController(repository);
    controller.Request = new HttpRequestMessage();
    controller.Configuration = new HttpConfiguration();

    // Act
    var response = controller.Get(10);

    // Assert
    Product product;
    Assert.IsTrue(response.TryGetContentValue<Product>(out product));
    Assert.AreEqual(10, product.Id);
}

Penting untuk mengatur Permintaan dan Konfigurasi pada pengontrol. Jika tidak, pengujian akan gagal dengan ArgumentNullException atau InvalidOperationException.

Lihat di sini untuk info lebih lanjut.

Dan Friedman
sumber
1

WebAPI 1 di sini dengan masalah serupa menggunakan VB.

Saya berhasil tanggapan hibrid di sini untuk membuatnya bekerja sesederhana ini:

Dim request As HttpRequestMessage = New HttpRequestMessage()
Return request.CreateResponse(HttpStatusCode.BadRequest, myCustomClassObject, GlobalConfiguration.Configuration)

Hanya memposting kalau-kalau itu membantu siapa pun.

Rudy Scoggins
sumber
0

Di kelas pengujian Anda, buat turunan dari kelas pengontrol. misalnyavar customerController= new CustomerController();

customerController.Request = new HttpRequestMessage();
customerController.Request.Properties.Add(HttpPropertyKeys.HttpConfigurationKey, new HttpConfiguration());
Kiran Chaudhari
sumber