Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 返回IActionResult的单元测试控制器方法_C#_Unit Testing_Asp.net Core_.net Core_Asp.net Core Webapi - Fatal编程技术网

C# 返回IActionResult的单元测试控制器方法

C# 返回IActionResult的单元测试控制器方法,c#,unit-testing,asp.net-core,.net-core,asp.net-core-webapi,C#,Unit Testing,Asp.net Core,.net Core,Asp.net Core Webapi,我正在构建一个ASP.NET核心WebAPI,并试图为控制器编写单元测试。我发现的大多数示例都来自旧的WebAPI/WebAPI2平台,似乎与新的核心控制器没有关联 我的控制器方法正在返回IActionResults。但是,IActionResult对象只有一个需要控制器上下文的executesultasync()方法。我正在手动实例化控制器,因此此实例中的控制器上下文为null,这会在调用executesultasync时导致异常。从本质上讲,这将引导我走上一条非常艰难的道路,让这些单元测试成

我正在构建一个ASP.NET核心WebAPI,并试图为控制器编写单元测试。我发现的大多数示例都来自旧的WebAPI/WebAPI2平台,似乎与新的核心控制器没有关联

我的控制器方法正在返回
IActionResults
。但是,
IActionResult
对象只有一个需要控制器上下文的
executesultasync()
方法。我正在手动实例化控制器,因此此实例中的控制器上下文为null,这会在调用
executesultasync
时导致异常。从本质上讲,这将引导我走上一条非常艰难的道路,让这些单元测试成功完成,而且非常混乱。我一直在想,必须有一种更简单/正确的方法来测试API控制器

此外,如果这有什么不同,我的控制器也没有使用async/await

我试图实现的简单示例:

控制器方法:

[HttpGet(Name = "GetOrdersRoute")]
public IActionResult GetOrders([FromQuery]int page = 0)
{
     try
     {
        var query = _repository.GetAll().ToList();

        int totalCount = query.Count;
        int totalPages = (int)Math.Ceiling((double)totalCount / pageSize) - 1;
        var orders = query.Skip(pageSize * page).Take(pageSize);

        return Ok(new
        {
           TotalCount = totalCount,
           TotalPages = totalPages,

           Orders = orders
        });
     }
     catch (Exception ex)
     {
        return BadRequest(ex);
     }
}
单元测试:

[Fact]
public void GetOrders_WithOrdersInRepo_ReturnsOk()
{
     // arrange
     var controller = new OrdersController(new MockRepository());

     // act
     IActionResult result = controller.GetOrders();

     // assert
     Assert.Equal(HttpStatusCode.OK, ????);
}

假设有点像

public IActionResult GetOrders() {
    var orders = repository.All();
    return Ok(orders);
}
本例中的控制器返回一个类

将结果强制转换为方法中返回的类型,并对该类型执行断言

[Fact]
public void GetOrders_WithOrdersInRepo_ReturnsOk() {
    // arrange
    var controller = new OrdersController(new MockRepository());

    // act
    var result = controller.GetOrders();
    var okResult = result as OkObjectResult;

    // assert
    Assert.IsNotNull(okResult);
    Assert.AreEqual(200, okResult.StatusCode);
}

你也可以做一些很酷的事情,比如:

    var result = await controller.GetOrders();//
    var okResult = result as ObjectResult;

    // assert
    Assert.NotNull(okResult);
    Assert.True(okResult is OkObjectResult);
    Assert.IsType<TheTypeYouAreExpecting>(okResult.Value);
    Assert.Equal(StatusCodes.Status200OK, okResult.StatusCode);
var result=await controller.GetOrders()//
var okResult=作为ObjectResult的结果;
//断言
Assert.NotNull(okResult);
True(okResult是OkObjectResult);
IsType(okResult.Value);
Assert.Equal(StatusCodes.Status200OK、okResult.StatusCode);

谢谢

您还可以使用ActionResult类作为控制器结果(假设您有类型订单)。 在这种情况下,您可以使用如下内容:

[ProducesResponseType(typeof(Orders), StatusCodes.Status200OK)]
public ActionResult<Orders> GetOrders()
{
    return service.GetOrders();
}
[Fact]
public void GetOrders_WithOrdersInRepo_ReturnsOk() {
    // arrange
    var controller = new OrdersController(new MockRepository());

    // act
    var result = controller.GetOrders();

    // assert
    var okResult = Assert.IsType<OkObjectResult>(result);
    Assert.IsNotNull(okResult);
    Assert.AreEqual(200, okResult.StatusCode);
}

没有正确地映射它

建议强制转换到
ObjectResult
的其他答案,但只有当您返回
OkObjectResult
\
NotFoundObjectResult
\等时,它才起作用。但服务器可以返回从
StatusCodeResult
派生的
NotFound
\
OkResult

例如:

public class SampleController : ControllerBase
{
    public async Task<IActionResult> FooAsync(int? id)
    {
        if (id == 0)
        {
            // returned "NotFoundResult" base type "StatusCodeResult"
            return NotFound();
        }

        if (id == 1)
        {
            // returned "StatusCodeResult" base type "StatusCodeResult"
            return StatusCode(StatusCodes.Status415UnsupportedMediaType);
        }

        // returned "OkObjectResult" base type "ObjectResult"
        return new OkObjectResult("some message");
    }
}

这样做的一个好方法是:

[ProducesResponseType(typeof(Orders), StatusCodes.Status200OK)]
public ActionResult<Orders> GetOrders()
{
    return service.GetOrders();
}
[Fact]
public void GetOrders_WithOrdersInRepo_ReturnsOk() {
    // arrange
    var controller = new OrdersController(new MockRepository());

    // act
    var result = controller.GetOrders();

    // assert
    var okResult = Assert.IsType<OkObjectResult>(result);
    Assert.IsNotNull(okResult);
    Assert.AreEqual(200, okResult.StatusCode);
}
[事实]
公共作废GetOrders\u with OrdersInRepo\u ReturnsOk(){
//安排
var controller=neworderscontroller(new MockRepository());
//表演
var result=controller.GetOrders();
//断言
var okResult=Assert.IsType(结果);
Assert.IsNotNull(okResult);
Assert.AreEqual(200,okResult.StatusCode);
}
公共异步任务调用扩展数据\u ReturnsHttpNotFound\u用于InvalidJobNum\u ReturnsStoredRxOrder()
{
var SCANICONTROLLER=新的SCANICONTROLLER(\u记录器,\u scanInService);
var okResult=等待扫描InControl.CallRxData(rxOrderRequest);
var notFoundResult=等待扫描InControl.CallRxData(invalidRxOrderRequest);
var okResultWithScanInCheckFalse=wait scanInController.CallRxData(rxOrderRequest);
var okResultWithEmptyAelAntiFakeDatas=等待扫描InControl.CallRxData(rxOrderRequest);
//断言
Assert.That(okResult,Is.TypeOf());
Assert.That(notFoundResult,Is.TypeOf());
Assert.IsFalse(((作为ObjectResult的okResultWithScanInCheckFalse)。作为RxOrder的值)。IsSecurity);`在此处输入代码`
}

显示
GetOrders
方法。你用那种方法返回什么。将结果强制转换为您在方法中返回的类型,并对其执行断言。您好(Nkosi:)我是否可以将整个结果对象与预期对象进行比较,以便检查返回代码和对象?现在,Assert.AreEqual(实际、预期)似乎不起作用。编辑:对象是一个字符串。“我必须做出断言吗?”松鼠杀手说,那是因为它们是两个独立的实例。您可以从结果中提取对象,并在控制两者的情况下对其进行比较。@Squirrelkiller,例如
Assert.AreEquan(myObject,okResult.Value)
where
myObject
被假定为从模拟中返回并在控制器操作中传递给
Ok()
的对象。当您仅返回Ok()时,会出现此问题没有内容,它正在重新调整OkResult而不是OkObjectResult。当强制转换到OkObjectResult时,它的状态代码不是总是200吗?
[Fact]
public void GetOrders_WithOrdersInRepo_ReturnsOk() {
    // arrange
    var controller = new OrdersController(new MockRepository());

    // act
    var result = controller.GetOrders();

    // assert
    var okResult = Assert.IsType<OkObjectResult>(result);
    Assert.IsNotNull(okResult);
    Assert.AreEqual(200, okResult.StatusCode);
}