web-dev-qa-db-ja.com

Request.CreateResponseを使用したASP.NET WebApiユニットテスト

ApiControllerの単体テストを作成しようとしており、いくつかの問題に直面しました。 Request.CreateResponseと呼ばれるニース拡張メソッドがあり、これは応答の生成に大いに役立ちます。

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

部分的なモックを使用せずに、または「新しいHttpResponseMessage(...)」を直接使用せずにCreateResponseをモックする方法はありますか?

143
asa

これを解決する別の方法は、次を実行することです。

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

Webapi 5.0にアップグレードする場合、これを次のように変更する必要があります。

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

これを行う必要がある理由は、Requestをコントローラーに設定する必要があるためです。そうしないと、Requestの拡張メソッドが機能しません。また、リクエストにHttpConfigurationを設定する必要があります。そうしないと、ルーティングやパイプラインの他の部分が正しく機能しません。

237
jonnii

次のように、テストしやすいようにコントローラーオブジェクトを設定できます。

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;

ASP.NET Web APIの単体テスト に関するPeter Provostの包括的なブログ投稿からコピー。

23
mono68

Web API 2の場合、単純に追加できます

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

そのようです

[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);
}

コントローラーで要求と構成を設定することが重要です。そうでない場合、テストはArgumentNullExceptionまたはInvalidOperationExceptionで失敗します。

詳細については here を参照してください。

2
Dan Friedman

VBを使用した同様の問題を伴うWebAPI 1。

このように簡単に機能させるために、ここでハイブリッド応答を管理できました。

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

誰かに役立つ場合にだけ投稿してください。

1
Rudy Scoggins

テストクラスで、コントローラークラスのインスタンスを作成します。例:var customerController= new CustomerController();

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