【问题标题】:How to get TempData in an integration test如何在集成测试中获取 TempData
【发布时间】:2017-07-26 14:00:30
【问题描述】:

我有一个具有以下操作的控制器:

[HttpGet]
public IActionResult Index()
{
    return View();
}

[HttpPost]
[Route(
    "/MyShop/OrderDetails/CancelOrder", 
    Name = UrlRouteDefinitions.MyShopOrderDetailsCancelOrder)]
[ValidateAntiForgeryToken]
public IActionResult CancelOrder(MyViewModel viewModel)
{
    var isCancelSuccessful = _orderBusinessLogic.CancelOrderById(viewModel.Order.Id);

    if (isCancelSuccessful)
    {
        //to show a success-message after the redirect
        this.TempData["SuccessCancelOrder"] = true;
    }

    return RedirectToRoute(UrlRouteDefinitions.MyShopOrderDetailsIndex, new
    {
        orderId = viewModel.Order.Id
    });
}

然后我在上面提到的Controller的视图中也有以下一段HTML:

<div class="panel-body">
    @if (TempData["SuccessCancelOrder"] != null) 
    {
        //show the message
        @TempData["SuccessCancelOrder"].ToString();
    }
</div>

现在我正在编写一个集成测试(下面的代码摘要)来检查CancelOrder() 方法是否按预期工作。在那里我想访问TempData 字典的值来检查它的正确性。

[TestMethod]
public void MyTest()
{
    try
    {
        //Arrange: create an Order with some Products
        var orderId = CreateFakeOrder();

        //Open the Order Details page for the arranged Order
        var httpRequestMessage = base.PrepareRequest(
            HttpMethod.Get,
            "/MyShop/OrderDetails?orderId=" + orderId,
            MediaTypeEnum.Html);

        var httpResponse    = base.Proxy.SendAsync(httpRequestMessage).Result;
        var responseContent = httpResponse.Content.ReadAsStringAsync().Result;
        var viewModel       = base.GetModel<MyViewModel>(responseContent);

        Assert.AreEqual(HttpStatusCode.OK, httpResponse.StatusCode);


        //Try to execute a POST to cancel the Order
        httpRequestMessage = base.PrepareRequest(
            HttpMethod.Post,
            "/MyShop/OrderDetails/CancelOrder",
            MediaTypeEnum.Html,
            httpResponse, content: viewModel);


        httpResponse = base.Proxy.SendAsync(httpRequestMessage).Result;
        var expectedRedirectLocation = $"{this.RelativeHomeUrl}/MyShop/OrderDetails?orderId=" + orderId;
        var receivedRedirectLocation = WebUtility.UrlDecode(httpResponse.Headers.Location.ToString());


        //we expect that the Order Details page will be reloaded 
        //with the ID of the already cancelled Order
        Assert.AreEqual(HttpStatusCode.Redirect, httpResponse.StatusCode);

        //-----------------------------------------------------------
        //here I'm going to re-execute a GET-request 
        //on the Order Details page. 
        //
        //Then I need to check the content of the message 
        //that's been written in the TempData
        //-----------------------------------------------------------
    }
    finally
    {
        //delete the arranged data
    }
}

无论如何,我不知道如何从我的集成测试中访问它。有人知道怎么做吗?有没有办法?

【问题讨论】:

    标签: c# asp.net-core asp.net-core-mvc integration-testing


    【解决方案1】:

    Controller.TempData 是公开的,因此您可以轻松访问它并检查您的键/值是否存在

    [TestMethod]
    public void TempData_Should_Contain_Message() {    
        // Arrange
        var httpContext = new DefaultHttpContext();
        var tempData = new TempDataDictionary(httpContext, Mock.Of<ITempDataProvider>());
        var controller = new TestController();
        controller.TempData = tempData;
    
        // Act
        var result = controller.DoSomething();
    
        //Assert
        controller.TempData["Message"]
            .Should().NotBeNull()
            .And.BeEquivalentTo("Hello World");
    
    }
    

    【讨论】:

    • 是的,确实如此,但由于您正在实例化控制器并执行操作,这不是单元测试吗?我在集成测试中所做的是将 HttpRequestMessage 对象发送到应用程序的各个端点并检查获得的 HttpResponseMessage 对象
    • 我知道这是一个单元测试。旨在显示访问该属性是可能的。您没有在 OP 中提供minimal reproducible example,所以我不打算猜测您的测试是如何进行的。
    猜你喜欢
    • 2018-03-26
    • 1970-01-01
    • 2016-07-03
    • 2013-06-25
    • 2019-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多