如何模拟HttpContext以在单元测试中设置Response.Cookie.Append()

huangapple go评论56阅读模式
英文:

How to Mock HttpContext to set Response.Cookie.Append() in UnitTest

问题

我需要模拟HttpContext并附加Cookie以在控制器中进行验证。

以下是我正在尝试的单元测试,但出现了空异常。

HomeController.ControllerContext = new ControllerContext();
HomeController.ControllerContext.HttpContext = new DefaultHttpContext();
HomeController.ControllerContext.HttpContext.Response.Cookies.Append("mycookie", cookieValue, cookieOptions);

这是我的控制器,我在其中检查Cookie是否为null。

public async Task<myDto> Identify() {

    // 从客户端获取标识符
    var identifier = identifiersService.GetIdentifier(HttpContext);
    if (!await identifiersService.IsValidAsync(identifier)) {
        if (HttpContext != null && HttpContext.Request.Cookies["mycookie"] != null) {
            HttpContext.Response.Cookies.Delete("mycookie");
        }
        throw new MyException(Factory.INVALID);
    }
}

有关如何从单元测试传递Cookie到控制器进行测试的任何建议都会受到欢迎。谢谢!

英文:

I need to mock HttpContext and append cookies to validate in controller.

Here is the unit Test I am trying but its failing with null exception.

HomeController.ControllerContext = new ControllerContext();
HomeController.ControllerContext.HttpContext = new DefaultHttpContext();
HomeController.ControllerContext.HttpContext.Response.Cookies.Append(&quot;mycookie&quot;, cookieValue, cookieOptions);

Here is the my controler where I am checking cooking null.

 public async Task&lt;myDto&gt; Identify() {

    // Get identifier from client
    var identifier = identifiersService.GetIdentifier(HttpContext);
    if (!await identifiersService.IsValidAsync(identifier)) {
        if (HttpContext != null &amp;&amp; HttpContext.Request.Cookies[&quot;mycookie&quot;] != null) {
            HttpContext.Response.Cookies.Delete(&quot;mycookie&quot;);
        }
        throw new MyException(Factory.INVALID);
    }

Any suggestion on how I can pass cookie from unittest to Controller to test. Thank you

答案1

得分: 1

你在响应中设置了 cookie,然后在请求中检查它。

  1. 模拟请求中的 Cookies 集合
  2. 将模拟的 HttpContext 传递给 ControllerContext
var cookiesMock = new Mock<IRequestCookieCollection>();
cookiesMock.SetupGet(c => c["mycookie"]).Returns(cookieValue);

var httpContextMock = new Mock<HttpContext>();
httpContextMock.Setup(ctx => ctx.Request.Cookies).Returns(cookiesMock.Object);

HomeController.ControllerContext = new ControllerContext()
{
    HttpContext = httpContextMock.Object
};

更新 #1

如果 cookies 可用,我需要删除 cookie。我如何模拟 Response.Cookies.Delete()

与请求 cookies 的处理方式类似:

var responseCookiesMock = new Mock<IResponseCookies>();
responseCookiesMock.Setup(c => c.Delete("mycookie")).Verifiable();
httpContextMock.Setup(ctx => ctx.Response.Cookies).Returns(responseCookiesMock.Object);

因此,完整的代码如下:

const string CookieKey = "mycookie";
var requestCookiesMock = new Mock<IRequestCookieCollection>();
requestCookiesMock.SetupGet(c => c[CookieKey]).Returns(cookieValue);

var responseCookiesMock = new Mock<IResponseCookies>();
responseCookiesMock.Setup(c => c.Delete(CookieKey)).Verifiable();

var httpContextMock = new Mock<HttpContext>();
httpContextMock.Setup(ctx => ctx.Request.Cookies).Returns(requestCookiesMock.Object);
httpContextMock.Setup(ctx => ctx.Response.Cookies).Returns(responseCookiesMock.Object);

HomeController.ControllerContext = new ControllerContext()
{
    HttpContext = httpContextMock.Object
};
英文:

You are setting the cookie on the response while you are checking it on the request.

  1. Mock the Cookies collection on the request
  2. Pass the mocked HttpContext to the ControllerContext
var cookiesMock = new Mock&lt;IRequestCookieCollection&gt;();
cookiesMock.SetupGet(c =&gt; c[&quot;mycookie&quot;]).Returns(cookieValue);

var httpContextMock = new Mock&lt;HttpContext&gt;();
httpContextMock.Setup(ctx =&gt; ctx.Request.Cookies).Returns(cookiesMock.Object);

HomeController.ControllerContext = new ControllerContext()
{
    HttpContext = httpContextMock.Object
};

UPDATE #1
> If cookies is available then I need to delete the cookie. How I can I mock Response.Cookies.Delete()?

Quite similarly what we did with the request cookies

var responseCookiesMock = new Mock&lt;IResponseCookies&gt;();
responseCookiesMock.Setup(c =&gt; c.Delete(&quot;mycookie&quot;))
                   .Verifiable();
httpContextMock.Setup(ctx =&gt; ctx.Response.Cookies)
               .Returns(responseCookiesMock.Object);

So, the full code would look like this

const string CookieKey = &quot;mycookie&quot;;
var requestCookiesMock = new Mock&lt;IRequestCookieCollection&gt;();
requestCookiesMock.SetupGet(c =&gt; c[CookieKey]).Returns(cookieValue);

var responseCookiesMock = new Mock&lt;IResponseCookies&gt;();
responseCookiesMock.Setup(c =&gt; c.Delete(CookieKey)).Verifiable();

var httpContextMock = new Mock&lt;HttpContext&gt;();
httpContextMock.Setup(ctx =&gt; ctx.Request.Cookies)
                .Returns(requestCookiesMock.Object);
httpContextMock.Setup(ctx =&gt; ctx.Response.Cookies)
                .Returns(responseCookiesMock.Object);

HomeController.ControllerContext = new ControllerContext()
{
    HttpContext = httpContextMock.Object
};

huangapple
  • 本文由 发表于 2023年3月9日 20:16:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/75684490.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定