簡體   English   中英

單元測試自定義IHttpactionResult

[英]Unit test custom IHttpactionResult

我正在嘗試在web api 2中創建一個自定義的IHttpActionResult類型,它將以HTML而不是json的形式返回內容。 我正在努力的是如何對返回我的新ActionResult類型的ApiController進行單元測試。 許多顯示如何對ApiController進行單元測試的示例告訴您將其強制轉換為OkNegotiatedContentResult,然后從中讀取內容屬性,但這似乎不適用於我的情況。 當我調試測試時,似乎永遠不會調用ExecuteAsync中的代碼塊。 我是否需要在單元測試中明確地執行此操作? 任何幫助都會很有幫助

這就是我的ActionResult的樣子

public class HtmlActionResult : IHttpActionResult
{
    String _html;
    public HtmlActionResult(string html)
    {
        _html = html;
    }

    public Task<System.Net.Http.HttpResponseMessage> ExecuteAsync(System.Threading.CancellationToken cancellationToken)
    {
        var response = new HttpResponseMessage(HttpStatusCode.OK);
        response.Content = new StringContent(_html );
        response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("text/html");
        return Task.FromResult(response);
    }
}

這是我的ApiController

public class HomeController : ApiController
{
    public IHttpActionResult Get(string page)
    {
        return new HtmlActionResult("<html></html>");
    }
}

這是我的測試方法

[TestMethod]
public async Task Get()
{
    //Arrenge
    HomeController controller = new HomeController();

    //Act
    IHttpActionResult result = controller.Get();

    //Assert
    //Assert.IsNotNull(result.Content);
}

使用流利斷言

IHttpActionResult result = await controller.Get()

HtmlActionResult htmlActionResult = result.Should()
                                          .BeOfType<HtmlActionResult>()
                                          .Which; // <-- the key feature
                                          // or .And

什么意思可以嵌套斷言:

IHttpActionResult result = await controller.Get()

result.Should().BeOfType<HtmlActionResult>()
      .Which.Content.Should().Be(expected);

或者就像@Spock分別建議測試一樣:

  • Get()返回IHttpActionResult,它實際上是HtmlActionResult
  • HtmlActionResult如何獨立於Get()工作

您不是在等待控制器操作完成 - 您應該將測試更改為(這是未經驗證的):

public async Task Get()
{
    // Arrange
    HomeController controller = new HomeController();

    // Act
    IHttpActionResult result = await controller.Get();

    // Assert
    Assert.IsNotNull(result.Content);
}

嘗試這個:

[TestMethod]
public void Get()
{
    //Arrenge
    var controller = new HomeController();

    //Act
    var result = controller.Get().Result as HtmlActionResult;

    //Assert
    Assert.IsNotNull(result);
}

請注意,您的測試可能無效,並且您不必等待Get方法,您可以使用.Result來運行任務。

此外,我將結果轉換為HtmlActionResult,如果結果是一個不同的ActionResult,如OkResult,或NotFoundResult,等等,結果將為Null。

希望有所幫助。

假設您正在使用WebAPI版本2,那么有關如何在ASP.NET站點上單元測試控制器的非常好的指南。

我和你的情況類似,並且讓我的控制器方法返回Tasks而不是IHttpActionResults有點不確定 - 我相信它更清晰。

我設法調整上面鏈接的返回HttpResponseMessage部分的測試操作下的代碼,以使我的單元測試按預期工作。

以下是我的場景的簡要概述:

public class XyzController : ApiController
{
    private readonly IDbContext _dbContext;

    public XyzController(IDbContext dbContext)
    {
        _dbContext = dbContext;
    }

    [HttpGet]
    [Route("this-is-optional")]
    public IHttpActionResult Get(<optional-params-here>)
    {
        // Do work
        ...

        // My data is an array of objects
        return Ok(data);
    }
}

[TestFixture]
public class XyzControllerTest
{
    [Test]
    public void Get_ReturnsSuccessfully()
    {
        // Arrange
        IDbContext testContext = MockDbContext.Create();
        ...
        // Populate textContext here
        ...
        XyzController xyzController = new XyzController(testContext)
        {
            // These are required or exceptions will be thrown
            Request = new HttpRequestMessage();
            Configuration = new HttpConfiguration()
        };            
        ...

        // Act
        var response = xyzController.Get(<params-if-required>).ExecuteAsync(CancellationToken.None);

        // Assert
        Assert.IsNotNull(response);
        Assert.IsTrue(response.IsCompleted);
        Assert.AreEqual(HttpStatusCode.OK, response.Result.StatusCode);

        // Assertions on returned data
        MyModel[] models;
        Assert.IsTrue(response.Result.TryGetContentValue<MyModel[]>(out models));
        Assert.AreEqual(5, model.Count());

        Assert.AreEqual(1, model.First().Id);
        ...
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM