当 运行 xUnit 测试时,控制器 returns 一个空的 IActionResult
Controller returns a null IActionResult when running xUnit test
我在通过单元测试时遇到了一些困难。
这是我的单元测试class:
[Collection(nameof(VehicleControllerCollection))]
public class DetectVin
{
private readonly VehicleControllerFixture _controllerFixture;
public DetectVin(VehicleControllerFixture controllerFixture)
{
_controllerFixture = controllerFixture;
}
[Fact]
public async Task ReturnsBadRequestGivenPictureIsNull()
{
var controllerMock = _controllerFixture.VehicleController;
controllerMock.Protected().Setup<bool>("HasAnyLicenseClaims", ItExpr.IsAny<string[]>()).Returns(true);
var result = await controllerMock.Object.DetectVin(null, 1) as BadRequestResult;
result.Should().NotBeNull();
}
}
它使用的 CollectionFixture
看起来像这样:
public class VehicleControllerFixture
{
public Mock<v1.v1._0.Vehicle.VehicleController> VehicleController { get; set; }
public VehicleControllerFixture()
{
var vehicleServiceMock = new Mock<IVehicleService>();
VehicleController = new Mock<v1.v1._0.Vehicle.VehicleController>(vehicleServiceMock.Object);
}
}
[CollectionDefinition(nameof(VehicleControllerCollection))]
public class VehicleControllerCollection : ICollectionFixture<VehicleControllerFixture>
{
}
正在测试的方法 DetectVin
如下所示:
[RequestSizeLimit(5242880)]
[HttpPost]
public async Task<IActionResult> DetectVin([FromBody]string picture, [FromQuery]int activityId)
{
if (!HasAnyLicenseClaims("ModuleMyWorkshopHGSService", "ModuleMyWorkshopToyotaService")) { return NotAllowed(); }
if (string.IsNullOrWhiteSpace(picture))
{
return BadRequest();
}
var result = await _vehicleService.DetectVin(picture);
if (string.IsNullOrWhiteSpace(result))
{
return UnprocessableEntity();
}
var activityVinDetection = new ActivityVinDetection
{
ActivityId = activityId,
UsedOnActivity = false,
Vin = result
};
_vehicleService.InsertActivityVinDetection(activityVinDetection);
return Ok(result);
}
我的问题是 DetectVin
方法总是 returns null
。即使我可以调试测试并逐步完成该方法,看到它实际上 returns BadRequest()
.
有人知道为什么会这样吗?
编辑:
这是 VehicleController
继承自的基本控制器:
public abstract class AIdpClaimsAuthController : BaseController, IAuthorizedController
{
public int WorkshopId
{
get
{
var wid = User.Claims.SingleOrDefault(sd => sd.Type == "sub");
if (wid == null || !int.TryParse(wid.Value, out int workshopId))
{
throw new System.Security.Authentication.AuthenticationException("Unauthorized");
}
return workshopId;
}
}
protected virtual bool HasAnyLicenseClaims(params string[] licenseClaims)
{
foreach (var claim in licenseClaims)
{
if (AuthorizationService.HasLicenseClaims(WorkshopId, claim))
{
return true;
}
}
return false;
}
}
这里是 AIdpClaimsAuthController
继承自的基本控制器:
public abstract class BaseController : Controller
{
private IAuthorizationService __authorizationService;
public IAuthorizationService AuthorizationService
{
get
{
if (__authorizationService == null)
{
__authorizationService = this.HttpContext.RequestServices.GetService(typeof(IAuthorizationService)) as IAuthorizationService;
}
return __authorizationService;
}
}
}
使用 MockBehaviour.Strict
找到了解决方案。
事实证明,我还需要模拟我的控制器为 BadRequest
方法生成的结果。
我在通过单元测试时遇到了一些困难。
这是我的单元测试class:
[Collection(nameof(VehicleControllerCollection))]
public class DetectVin
{
private readonly VehicleControllerFixture _controllerFixture;
public DetectVin(VehicleControllerFixture controllerFixture)
{
_controllerFixture = controllerFixture;
}
[Fact]
public async Task ReturnsBadRequestGivenPictureIsNull()
{
var controllerMock = _controllerFixture.VehicleController;
controllerMock.Protected().Setup<bool>("HasAnyLicenseClaims", ItExpr.IsAny<string[]>()).Returns(true);
var result = await controllerMock.Object.DetectVin(null, 1) as BadRequestResult;
result.Should().NotBeNull();
}
}
它使用的 CollectionFixture
看起来像这样:
public class VehicleControllerFixture
{
public Mock<v1.v1._0.Vehicle.VehicleController> VehicleController { get; set; }
public VehicleControllerFixture()
{
var vehicleServiceMock = new Mock<IVehicleService>();
VehicleController = new Mock<v1.v1._0.Vehicle.VehicleController>(vehicleServiceMock.Object);
}
}
[CollectionDefinition(nameof(VehicleControllerCollection))]
public class VehicleControllerCollection : ICollectionFixture<VehicleControllerFixture>
{
}
正在测试的方法 DetectVin
如下所示:
[RequestSizeLimit(5242880)]
[HttpPost]
public async Task<IActionResult> DetectVin([FromBody]string picture, [FromQuery]int activityId)
{
if (!HasAnyLicenseClaims("ModuleMyWorkshopHGSService", "ModuleMyWorkshopToyotaService")) { return NotAllowed(); }
if (string.IsNullOrWhiteSpace(picture))
{
return BadRequest();
}
var result = await _vehicleService.DetectVin(picture);
if (string.IsNullOrWhiteSpace(result))
{
return UnprocessableEntity();
}
var activityVinDetection = new ActivityVinDetection
{
ActivityId = activityId,
UsedOnActivity = false,
Vin = result
};
_vehicleService.InsertActivityVinDetection(activityVinDetection);
return Ok(result);
}
我的问题是 DetectVin
方法总是 returns null
。即使我可以调试测试并逐步完成该方法,看到它实际上 returns BadRequest()
.
有人知道为什么会这样吗?
编辑:
这是 VehicleController
继承自的基本控制器:
public abstract class AIdpClaimsAuthController : BaseController, IAuthorizedController
{
public int WorkshopId
{
get
{
var wid = User.Claims.SingleOrDefault(sd => sd.Type == "sub");
if (wid == null || !int.TryParse(wid.Value, out int workshopId))
{
throw new System.Security.Authentication.AuthenticationException("Unauthorized");
}
return workshopId;
}
}
protected virtual bool HasAnyLicenseClaims(params string[] licenseClaims)
{
foreach (var claim in licenseClaims)
{
if (AuthorizationService.HasLicenseClaims(WorkshopId, claim))
{
return true;
}
}
return false;
}
}
这里是 AIdpClaimsAuthController
继承自的基本控制器:
public abstract class BaseController : Controller
{
private IAuthorizationService __authorizationService;
public IAuthorizationService AuthorizationService
{
get
{
if (__authorizationService == null)
{
__authorizationService = this.HttpContext.RequestServices.GetService(typeof(IAuthorizationService)) as IAuthorizationService;
}
return __authorizationService;
}
}
}
使用 MockBehaviour.Strict
找到了解决方案。
事实证明,我还需要模拟我的控制器为 BadRequest
方法生成的结果。