ASP.NET测试Api控制器:Uri(Request.GetEncodedUrl()...)返回null [英] ASP.NET Testing Api controller: Uri(Request.GetEncodedUrl()...) returns null

查看:42
本文介绍了ASP.NET测试Api控制器:Uri(Request.GetEncodedUrl()...)返回null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在测试ASP.NET Core Api post方法,但遇到System.NullReferenceException导致测试失败.

I am testing an ASP.NET Core Api post method, but I get a System.NullReferenceException causing my test to fail.

当我尝试返回Created()-ActionResult时,将出现null异常,如下所示:

The null exception appears when I try to return a Created()-ActionResult, like this:

return Created(new Uri(Request.GetEncodedUrl() + "/" + personDto.Id), personDto);

我的personDto.Id也不是personDto不为null,但是Uri()的结果返回null.我已经用谷歌搜索了,但是没有找到解决方案,但是我相信我必须以某种方式模拟Uri()方法(对于测试和asp.net我是新手).在对SQL Server进行实时"测试时,Api可以很好地工作.

My personDto.Id nor the personDto is not null, but the result of the Uri() returns null. I have googled but not found a solution, but I believe I have to mock the Uri()-method in some way (I am new to testing and asp.net in general). The Api works well when testing it "live" against a SQL Server.

我正在使用Moq和NUnit进行测试,以下是我的设置和测试方法的一部分:

I am using Moq and NUnit to test, and below is part of my Setup and Test-methods:

public void SetUp()
{
    _mapper = GenerateConcreteInstance();

    _personService = new Mock<IPersonService>();

    _personService.Setup(ps => ps.Create(It.IsAny<Person>())).Verifiable();

    _controller = new PeopleController(_personService.Object, _mapper);
}

[Test]
public void CreatePerson_WhenCalled_IsNotNull()
{
    var personDto = new PersonDto()
    {
        Id = 3,
        Firstname = "Karl",
        Lastname = "Karlsson",
        City = "Oslo",
        Email = "karl.karlsson@test.com"
    };

    var result = _controller.CreatePerson(personDto);

    var createdResult = result as CreatedResult;

    Assert.IsNotNull(createdResult);
}

我要测试的控制器:

[HttpPost]
public IActionResult CreatePerson(PersonDto personDto)
{
    if (!ModelState.IsValid)
        return BadRequest();

    var person = _mapper.Map<PersonDto, Person>(personDto);
    person.DateCreated = DateTime.Now;

    _personService.Create(person);
    _personService.Save();

    personDto.Id = person.Id;

    return Created(new Uri(Request.GetEncodedUrl() + "/" + personDto.Id), personDto);
}

如何正确设置此测试以避免null异常?如果我的测试在任何其他方面都不好,将对如何解决此问题以及总体上的指针有所帮助.

How do I setup this test properly to avoid the null exception? Would appreciate any help on how to solve this problem, and pointers in general, if my test is not good in any other way.

更新

我已经像这样修改了测试.我在正确的轨道上吗?

I have modifed the test like this. Am I on the right track?

public void CreatePerson_WhenCalled_IsNotNull()
{
    var personDto = new PersonDto()
    {
        Id = 3,
        Firstname = "Karl",
        Lastname = "Karlsson",
        City = "Oslo",
        Email = "karl.karlsson@test.com"
    };

    var request = new Mock<HttpRequest>();
    request.Setup(x => x.Headers).Returns(
        new HeaderDictionary {
        {"X-Requested-With", "XMLHttpRequest"}
    });


    var context = new Mock<HttpContext>();
    context.Setup(x => x.Request).Returns(request.Object);

    _controller.ControllerContext = new ControllerContext()
    {
        HttpContext = context.Object
    };

    var result = _controller.CreatePerson(personDto);

    var createdResult = result as CreatedResult;

    Assert.IsNotNull(createdResult);
}

推荐答案

Request.GetEncodedUrl()扩展依赖于具有有效的请求.

Request.GetEncodedUrl() extension relies on having a valid request.

/// <summary>
/// Returns the combined components of the request URL in a fully escaped form suitable for use in HTTP headers
/// and other HTTP operations.
/// </summary>
/// <param name="request">The request to assemble the uri pieces from.</param>
/// <returns>The encoded string version of the URL from <paramref name="request"/>.</returns>
public static string GetEncodedUrl(this HttpRequest request)
{
    return BuildAbsolute(request.Scheme, request.Host, request.PathBase, request.Path, request.QueryString);
}

来源

哪个会失败

if (scheme == null)
{
    throw new ArgumentNullException(nameof(scheme));
}

来源

没有与所示示例关联的上下文或请求,因此我建议提供一个有效的上下文,其中包含必要的成员,以便按预期进行测试.

There is no context or request associated with the shown example so I suggest providing a valid context with the necessary members populated for the test to be exercised as expected.

//...omitted for brevity

var httpContext = new DefaultHttpContext();
//http://localhost/example
httpContext.Request.Scheme = "http";
httpContext.Request.Host = new HostString("localhost");

//Controller needs a controller context 
var controllerContext = new ControllerContext() {
    HttpContext = httpContext,
};
//assign context to controller
_controller.ControllerContext = controllerContext;

//...omitted for brevity

这篇关于ASP.NET测试Api控制器:Uri(Request.GetEncodedUrl()...)返回null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆