控制器的单元测试未按预期工作

Unit test for controller doesn't work as expected

我创建了以下控制器:

[HttpGet(“{provId}/m”)]
public async Task<IActionResult> GetMForProv (int provId)
{
   var result = await _mediator.Send(new GetMForProvQuery() { ProvId = provId });

   if (result == null)
   {
      return NotFound();
   }

   return Ok(result);
}

以及以下单元测试:

public class GetMForProvTest
{
   private readonly ProvController _sut;
   private readonly Mock<IMediator> _mediator;
   private readonly Mock<IConfiguration> _configuration;

   public GetMForProvTest()
   {
      _mediator = new Mock<IMediator>();
      _configuration = new Mock<Iconfiguration>();

      _mediator.Setup(x => x.Send(It.IsAny<GetMForProvQuery>(), It.IsAny<CancellationToken>()))
           .ReturnsAsync(new CatDto());

      _sut = new ProvController(_mediator.Object, _configuration.Object);
   }

   [Fact]
   public async Task ShouldReturnNotFoundResult_AfterGetMForProv()
   {
      var result = await _sut.GetMForProv(123); // this providerId does not exist

      Assert.Equal(StatusCodes.Status404NotFound, (result as NotFoundObjectResult).StatusCode);
   }

当我运行以上测试时,在线Assert.Equal(…)我得到

Object reference not set to an instance of an object.

(… as NotFoundObjectResult returned null.

我怎样才能得到这份工作?

尝试修复线路:

.ReturnsAsync(new CatDto());

.ReturnsAsync((CatDto)null);

因为你 return CatDto 对象和铸造的结果 (result as NotFoundObjectResult) 是 null

Chetan 在评论中提供了答案:

I think you need to cast to NotFoundResult instead of NotFoundObjectResult

您没有在 return NotFound() 中传递对象,因此您应该改用 NotFoundResultAs 运算符返回 null,这就是您收到异常的原因。将断言更新为:

Assert.Equal(StatusCodes.Status404NotFound, (result as NotFoundResult).StatusCode);

这已经过测试,并且正在使用您的原始设置为我工作:

_mediator.Setup(x => x.Send(It.IsAny<GetMForProvQuery>(), It.IsAny<CancellationToken>()))
         .ReturnsAsync(() => null);

在你澄清你正在使用可选参数之前的原始答案

您确定为 _mediator.Send 设置了正确的重载吗?您似乎正在为 Send in:

设置不同的重载
_mediator.Setup(x => x.Send(It.IsAny<GetMForProvQuery>(), It.IsAny<CancellationToken>()))...

需要2个参数。但是,您在控制器中使用单个参数调用它:

var result = await _mediator.Send(new GetMForProvQuery() { ProvId = provId })

您能否尝试设置单个参数重载并传递一个返回 null 的操作:

_mediator.Setup(x => x.Send(It.IsAny<GetMForProvQuery>()))
           .ReturnsAsync(() => null);