等待模拟方法时单元测试中的 NRE
NRE in a unit test when await a mocked method
我正在尝试使用 mstest 为 .net Core 3 Web API 构建单元测试。
我也在用:
- 自动夹具
- 起订量
- AutoFixture.AutoMoq
这个单元测试应该 return 在没有找到啤酒时 NotFound()
响应。
private IFixture _fixture;
private BeerController _beerController;
private Mock<IBeerService> _mockBeerService;
[TestInitialize]
public void Initialize()
{
_fixture = new Fixture().Customize(new AutoMoqCustomization());
_mockBeerService = _fixture.Freeze<Mock<IBeerService>>();
_beerController = _fixture.Create<BeerController>();
}
[TestMethod]
public async Task WhenCallGetBeerWithoutMatchReturnNotFound404()
{
//Arrange
int beerId = _fixture.Create<int>();
_mockBeerService.Setup(x => x.GetBeer(It.IsAny<int>())).Returns((Task<Beer>)null);
//Act
var actionResult = await _beerController.Get(beerId);
//Assert
Assert.IsInstanceOfType(actionResult.Result, typeof(NotFoundResult));
}
这就是我要测试的功能:
[HttpGet("{beerId:int}")]
public async Task<ActionResult<beer>> Get(int beerId)
{
try
{
var beer = await _beerService.Getbeer(beerId);
if (beer == null) return NotFound();
return Ok(beer);
}
catch (Exception)
{
return BadRequest();
}
}
但我 运行 在这行代码中遇到 Object reference not set to an instance of an object.
异常:var beer = await _biereService.Getbeer(beerId);
这是堆栈跟踪:
at BeerProject.Controllers.BeerController.<Get>d__2.MoveNext() in F:\DevProjects\Repos\API_BeerProject\BeerProject\Controllers\BeerController.cs:line 29
我用这个测试测试了return Ok(beer)
:
[TestMethod]
public async Task WhenCallGetBeerWithMatchReturnOk200()
{
//Arrange
int beerId = _fixture.Create<int>();
var beer = _fixture.Create<Task<Beer>>();
_mockBeerService.Setup(x => x.GetBeer(It.IsAny<int>())).Returns(beer);
//Act
var actionResult = await _beerController.Get(beerId);
//Assert
Assert.IsInstanceOfType(actionResult.Result, typeof(OkObjectResult));
}
它工作正常。
所以我猜他不喜欢 WhenCallGetBeerWithoutMatchReturnNotFound404()
中的 .Returns((Task<Beer>)null)
在您的控制器中,您假设 GetBeer
return 是一个非空任务,因为您无条件地等待它。然后你检查结果,啤酒,看看它是否 null
:
var beer = await _beerService.Getbeer(beerId);
if (beer == null) return NotFound();
在这一行中,您不是 return 喝 null
啤酒的任务,而是 return 执行 null
任务:
_mockBeerService.Setup(x => x.GetBeer(It.IsAny<int>())).Returns((Task<Beer>)null);
因此,等待 null
会导致您的 NullReferenceException
。
如果您想 return null
啤酒作为任务的结果,您需要改为使用:
_mockBeerService.Setup(x => x.GetBeer(It.IsAny<int>())).Returns(Task.FromResult<Beer>(null));
甚至:
_mockBeerService.Setup(x => x.GetBeer(It.IsAny<int>())).ReturnsAsync(null);
我正在尝试使用 mstest 为 .net Core 3 Web API 构建单元测试。
我也在用:
- 自动夹具
- 起订量
- AutoFixture.AutoMoq
这个单元测试应该 return 在没有找到啤酒时 NotFound()
响应。
private IFixture _fixture;
private BeerController _beerController;
private Mock<IBeerService> _mockBeerService;
[TestInitialize]
public void Initialize()
{
_fixture = new Fixture().Customize(new AutoMoqCustomization());
_mockBeerService = _fixture.Freeze<Mock<IBeerService>>();
_beerController = _fixture.Create<BeerController>();
}
[TestMethod]
public async Task WhenCallGetBeerWithoutMatchReturnNotFound404()
{
//Arrange
int beerId = _fixture.Create<int>();
_mockBeerService.Setup(x => x.GetBeer(It.IsAny<int>())).Returns((Task<Beer>)null);
//Act
var actionResult = await _beerController.Get(beerId);
//Assert
Assert.IsInstanceOfType(actionResult.Result, typeof(NotFoundResult));
}
这就是我要测试的功能:
[HttpGet("{beerId:int}")]
public async Task<ActionResult<beer>> Get(int beerId)
{
try
{
var beer = await _beerService.Getbeer(beerId);
if (beer == null) return NotFound();
return Ok(beer);
}
catch (Exception)
{
return BadRequest();
}
}
但我 运行 在这行代码中遇到 Object reference not set to an instance of an object.
异常:var beer = await _biereService.Getbeer(beerId);
这是堆栈跟踪:
at BeerProject.Controllers.BeerController.<Get>d__2.MoveNext() in F:\DevProjects\Repos\API_BeerProject\BeerProject\Controllers\BeerController.cs:line 29
我用这个测试测试了return Ok(beer)
:
[TestMethod]
public async Task WhenCallGetBeerWithMatchReturnOk200()
{
//Arrange
int beerId = _fixture.Create<int>();
var beer = _fixture.Create<Task<Beer>>();
_mockBeerService.Setup(x => x.GetBeer(It.IsAny<int>())).Returns(beer);
//Act
var actionResult = await _beerController.Get(beerId);
//Assert
Assert.IsInstanceOfType(actionResult.Result, typeof(OkObjectResult));
}
它工作正常。
所以我猜他不喜欢 WhenCallGetBeerWithoutMatchReturnNotFound404()
.Returns((Task<Beer>)null)
在您的控制器中,您假设 GetBeer
return 是一个非空任务,因为您无条件地等待它。然后你检查结果,啤酒,看看它是否 null
:
var beer = await _beerService.Getbeer(beerId);
if (beer == null) return NotFound();
在这一行中,您不是 return 喝 null
啤酒的任务,而是 return 执行 null
任务:
_mockBeerService.Setup(x => x.GetBeer(It.IsAny<int>())).Returns((Task<Beer>)null);
因此,等待 null
会导致您的 NullReferenceException
。
如果您想 return null
啤酒作为任务的结果,您需要改为使用:
_mockBeerService.Setup(x => x.GetBeer(It.IsAny<int>())).Returns(Task.FromResult<Beer>(null));
甚至:
_mockBeerService.Setup(x => x.GetBeer(It.IsAny<int>())).ReturnsAsync(null);