C# 使用Moq在服务上模拟异步方法

C# 使用Moq在服务上模拟异步方法,c#,unit-testing,asp.net-core,moq,mstest,C#,Unit Testing,Asp.net Core,Moq,Mstest,我在一个.Net核心API中工作。我希望在ArtistsController上对GetArtists方法进行单元测试 代码 这是我的控制器代码: [Route("artists")] public class ArtistsController : Controller { private readonly IPermissionsService _permissionsService; private readonly IArtistsService _artistsService;

我在一个.Net核心API中工作。我希望在
ArtistsController
上对
GetArtists
方法进行单元测试

代码

这是我的控制器代码:

[Route("artists")]
public class ArtistsController : Controller
{
  private readonly IPermissionsService _permissionsService;
  private readonly IArtistsService _artistsService;
  private readonly ILogger<ArtistsController> _logger;

  public ArtistsController(IPermissionsService permissionsService, IArtistsService artistsService, ILogger<ArtistsController> logger)
  {
    _permissionsService = permissionsService ?? throw new ArgumentNullException(nameof(permissionsService));
    _artistsService = artistsService ?? throw new ArgumentNullException(nameof(artistsService));
    _logger = logger ?? throw new ArgumentNullException(nameof(logger));
  }

  [HttpGet]
  public async Task<IActionResult> GetArtists()
  {
    var permissions = await _permissionsService.GetPermissionsAsync(HttpContext);
    var artists = _artistsService.GetAllArtists(permissions.UserId, permissions.IsAdministrator);
    return Ok( new { artists });
  }
}
当我运行该命令时,会出现以下错误:

Project.ArtistsControllerTests.GetArtists\u ReturnsOKStatusCode引发异常: System.NullReferenceException:对象引用未设置为对象的实例

调试时,我发现
var permissions=await\u permissions service.GetPermissionsAsync(HttpContext)返回
null

我一定对我嘲笑的方式有意见:

_mockPermissionsService
    .Setup(service => service.GetPermissionsAsync(It.IsAny<HttpContext>()))
\u mockpermissions服务
.Setup(service=>service.GetPermissionsAsync(It.IsAny()))

为什么上述操作不起作用?

ArtistsControllerTests.Setup()
未被调用,因此在执行测试之前不会设置模拟

因此,当执行测试时,它们将返回null

您的设置代码是正确的,只是没有被调用

Setup
方法更改为构造函数

public ArtistsControllerTests() {
    _mockArtistsService.Reset();
    _mockPermissionsService
      .Setup(service => service.GetPermissionsAsync(It.IsAny<HttpContext>()))
      .Returns(Task.FromResult(new Permissions { UserId = "112233", IsAdministrator = false }));
    _mockArtistsService.Setup(service => service.GetAllArtists(It.IsAny<string>(), false)).Returns(new ArtistCardDtoCollection());
}
或者只是将排列移动到测试本身中

[TestMethod]
public async Task GetArtists_ReturnsOKStatusCode() {
    // arrange
    _mockArtistsService.Reset();
    _mockPermissionsService
      .Setup(service => service.GetPermissionsAsync(It.IsAny<HttpContext>()))
      .Returns(Task.FromResult(new Permissions { UserId = "112233", IsAdministrator = false }));
    _mockArtistsService.Setup(service => service.GetAllArtists(It.IsAny<string>(), false)).Returns(new ArtistCardDtoCollection());
    var artistsController = new ArtistsController(_mockPermissionsService.Object, _mockArtistsService.Object, _mockLogger.Object);
    // act
    var getArtistsResult = await artistsController.GetArtists();
    var okResult = getArtistsResult as OkObjectResult;
    // assert
    Assert.IsInstanceOfType(okResult, typeof(OkObjectResult));
}
[TestMethod]
公共异步任务GetArtisters\u ReturnsOKStatusCode(){
//安排
_mockartistservice.Reset();
_模拟许可服务
.Setup(service=>service.GetPermissionsAsync(It.IsAny()))
.Returns(Task.FromResult(新权限{UserId=“112233”,IsAdministrator=false}));
_mockArtistsService.Setup(service=>service.GetAllArtists(It.IsAny(),false)).Returns(new ArtistCardDtoCollection());
var artistsController=新的artistsController(\u mockPermissionsService.Object、\u mockArtistsService.Object、\u mockLogger.Object);
//表演
var getArtistsResult=等待artistsController.GetArtists();
var-okResult=getArtistsResult作为OkObjectResult;
//断言
IsInstanceOfType(okResult,typeof(OkObjectResult));
}

您能检查哪个变量返回空值吗?不要运行测试并将结果放在这里;自己调试。有东西是空的。对不起,我确实试过调试@CodeCaster,我忘了添加那个信息,我很抱歉。添加了一个屏幕广播来显示正在发生的事情。@Ciwan在
GetArtists
中放了一个断点,然后逐步执行。可能是您没有正确配置其中一个模拟
public ArtistsControllerTests() {
    _mockArtistsService.Reset();
    _mockPermissionsService
      .Setup(service => service.GetPermissionsAsync(It.IsAny<HttpContext>()))
      .Returns(Task.FromResult(new Permissions { UserId = "112233", IsAdministrator = false }));
    _mockArtistsService.Setup(service => service.GetAllArtists(It.IsAny<string>(), false)).Returns(new ArtistCardDtoCollection());
}
[TestInitialize]
public void Setup() {
    _mockArtistsService.Reset();
    _mockPermissionsService
      .Setup(service => service.GetPermissionsAsync(It.IsAny<HttpContext>()))
      .Returns(Task.FromResult(new Permissions { UserId = "112233", IsAdministrator = false }));
    _mockArtistsService.Setup(service => service.GetAllArtists(It.IsAny<string>(), false)).Returns(new ArtistCardDtoCollection());
}
[TestMethod]
public async Task GetArtists_ReturnsOKStatusCode() {
    // arrange
    _mockArtistsService.Reset();
    _mockPermissionsService
      .Setup(service => service.GetPermissionsAsync(It.IsAny<HttpContext>()))
      .Returns(Task.FromResult(new Permissions { UserId = "112233", IsAdministrator = false }));
    _mockArtistsService.Setup(service => service.GetAllArtists(It.IsAny<string>(), false)).Returns(new ArtistCardDtoCollection());
    var artistsController = new ArtistsController(_mockPermissionsService.Object, _mockArtistsService.Object, _mockLogger.Object);
    // act
    var getArtistsResult = await artistsController.GetArtists();
    var okResult = getArtistsResult as OkObjectResult;
    // assert
    Assert.IsInstanceOfType(okResult, typeof(OkObjectResult));
}