How to unit test whether a Core MVC controller action calls ControllerBase.Problem()

前端 未结 2 1444
你的背包
你的背包 2021-01-12 16:26

We have a controller that derives from ControllerBase with an action like this:

public async Task Get(int id)
{
  try
  {
           


        
2条回答
  •  轻奢々
    轻奢々 (楼主)
    2021-01-12 17:26

    The null exception is because of a missing ProblemDetailsFactory

    In this case the controller needs to be able to create ProblemDetails instance via

    [NonAction]
    public virtual ObjectResult Problem(
        string detail = null,
        string instance = null,
        int? statusCode = null,
        string title = null,
        string type = null)
    {
        var problemDetails = ProblemDetailsFactory.CreateProblemDetails(
            HttpContext,
            statusCode: statusCode ?? 500,
            title: title,
            type: type,
            detail: detail,
            instance: instance);
    
        return new ObjectResult(problemDetails)
        {
            StatusCode = problemDetails.Status
        };
    }
    

    Source

    ProblemDetailsFactory is a settable property

    public ProblemDetailsFactory ProblemDetailsFactory
    {
        get
        {
            if (_problemDetailsFactory == null)
            {
                _problemDetailsFactory = HttpContext?.RequestServices?.GetRequiredService();
            }
    
            return _problemDetailsFactory;
        }
        set
        {
            if (value == null)
            {
                throw new ArgumentNullException(nameof(value));
            }
    
            _problemDetailsFactory = value;
        }
    }
    

    Source

    that could be mocked and populated when testing in isolation.

    [TestMethod]
    public async Task GetCallsProblemOnInvalidId() {
        //Arrange
        var problemDetails = new ProblemDetails() {
            //...populate as needed
        };
        var mock = new Mock();
        mock
            .Setup(_ => _.CreateProblemDetails(
                It.IsAny(),
                It.IsAny(),
                It.IsAny(),
                It.IsAny(),
                It.IsAny(),
                It.IsAny())
            )
            .Returns(problemDetails)
            .Verifyable();
    
        var sut = new MyController(...);
        sut.ProblemDetailsFactory = mock.Object;
    
        //...
    
        //Act
        var result = await sut.Get(someInvalidId);
    
        //Assert
        mock.Verify();//verify setup(s) invoked as expected
    
        //...other assertions
    }
    

提交回复
热议问题