Home > Software engineering >  Controller returns a null IActionResult when running xUnit test
Controller returns a null IActionResult when running xUnit test

Time:04-11

I'm having some difficulties making my unit test pass.

This is my unit 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();
    }
}

It is using a CollectionFixture that looks like this:

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>
{
}

And the method that's being test DetectVin looks like this:

[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);
}

My problem is that the DetectVin method always returns null. This is even though I can debug the test and step through the method just fine, seeing that it actually returns the BadRequest().

Anyone has any idea why that could be?

EDIT:

Here is the base controller that the VehicleController inherits from:

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;
    }
}

And here is the base controller that the AIdpClaimsAuthController inherits from:

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;
        }
    }
}

CodePudding user response:

Found the solution using MockBehaviour.Strict. Turns out that I also needed to mock the result that my controller generated for the BadRequest method.

  • Related