控制器的单元测试未按预期工作
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()
中传递对象,因此您应该改用 NotFoundResult
。 As
运算符返回 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);
我创建了以下控制器:
[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 ofNotFoundObjectResult
您没有在 return NotFound()
中传递对象,因此您应该改用 NotFoundResult
。 As
运算符返回 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);