使用最小起订量的服务模拟异步方法
Mock Async method on Service using Moq
我在 .Net Core 工作 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 });
}
}
这是我正在写的测试方法:
[TestClass]
public class ArtistsControllerTests
{
private readonly Mock<IPermissionsService> _mockPermissionsService = new Mock<IPermissionsService>();
private readonly Mock<IArtistsService> _mockArtistsService = new Mock<IArtistsService>();
private readonly Mock<ILogger<ArtistsController>> _mockLogger = new Mock<ILogger<ArtistsController>>();
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
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));
}
}
这里是 IPermissionsService
和 Permissions
class。
public interface IPermissionsService
{
Task<Permissions> GetPermissionsAsync(HttpContext httpContext);
}
public class Permissions
{
public string UserId { get; set; }
public bool IsAdministrator { get; set; }
}
当我 运行 时,出现以下错误:
Project.ArtistsControllerTests.GetArtists_ReturnsOKStatusCode threw exception:
System.NullReferenceException: Object reference not set to an instance of an object.
调试的时候发现var permissions = await _permissionsService.GetPermissionsAsync(HttpContext);
returns null
.
我的嘲笑方式肯定有问题:
_mockPermissionsService
.Setup(service => service.GetPermissionsAsync(It.IsAny<HttpContext>()))
为什么上面的方法不起作用?
ArtistsControllerTests.Setup()
未被调用,因此在执行测试之前未设置模拟。
因此,当进行测试时,它们将 return 无效。
您的设置代码是正确的,只是没有被调用。
要么将 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());
}
或者用[TestInitilize]
属性修饰方法
[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));
}
我在 .Net Core 工作 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 });
}
}
这是我正在写的测试方法:
[TestClass]
public class ArtistsControllerTests
{
private readonly Mock<IPermissionsService> _mockPermissionsService = new Mock<IPermissionsService>();
private readonly Mock<IArtistsService> _mockArtistsService = new Mock<IArtistsService>();
private readonly Mock<ILogger<ArtistsController>> _mockLogger = new Mock<ILogger<ArtistsController>>();
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
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));
}
}
这里是 IPermissionsService
和 Permissions
class。
public interface IPermissionsService
{
Task<Permissions> GetPermissionsAsync(HttpContext httpContext);
}
public class Permissions
{
public string UserId { get; set; }
public bool IsAdministrator { get; set; }
}
当我 运行 时,出现以下错误:
Project.ArtistsControllerTests.GetArtists_ReturnsOKStatusCode threw exception: System.NullReferenceException: Object reference not set to an instance of an object.
调试的时候发现var permissions = await _permissionsService.GetPermissionsAsync(HttpContext);
returns null
.
我的嘲笑方式肯定有问题:
_mockPermissionsService
.Setup(service => service.GetPermissionsAsync(It.IsAny<HttpContext>()))
为什么上面的方法不起作用?
ArtistsControllerTests.Setup()
未被调用,因此在执行测试之前未设置模拟。
因此,当进行测试时,它们将 return 无效。
您的设置代码是正确的,只是没有被调用。
要么将 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());
}
或者用[TestInitilize]
属性修饰方法
[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));
}