How to add exception test for next Http call that returns json

[HttpPost]
[Route("TnC")]
public IHttpActionResult TnC(CustomViewModel myViewModel)
{
    try
    {
        return Json(_Internal.TnC(myViewModel, LoggedInUser));
    }
    catch (BusinessException exception)
    {
        return Json(BuildErrorModelBase(exception));
    }
}

Where _Internalis the Service with 99.99% guaranteed time and non-formalized fault contract interfaces.

Exceptions handled at my application level (business level) as root class BusinessException

Where BusinessException is defined as follows

public class BusinessException : Exception
{
    BusinessException()...
    BusinessExceptionFoo()...
    BusinessExceptionBar()...
    //...
}

And the current testing method

Make: Add Exception Test

[TestMethod]
[ExpectedException(typeof(BusinessException),
        "Not a valid Business Case")]
public void TnCTest()
{
    var bookingService = myContainer.Resolve<mySvc>();

    var controller = new LinkBookingController(mySvc, myContainer);
    var expectedResult = controller.TnC(new myViewModel
    {
        ...params
    });

    var actualResult = GetData<Result<myViewModel>>(expectedResult);

    Assert.AreEqual(expectedResult, actualResult);
}

expectedResult==actualResultdoes not check the code exception block. How to create a request that causes the service to throw an exception, besides manually removing the Ethernet cable to get this type of server error.

The best I could come up with was

#if DEBUG && UnitTestExceptions
        throw new BusinessException();
#endif

But there is a better option.

+6
2

, .

, ExceptionHandler. , , - (DRY).

public class WebApiExceptionHandler : ExceptionHandler {

    public override void Handle(ExceptionHandlerContext context) {
        var innerException = context.ExceptionContext.Exception;
        // Ignore HTTP errors
        if (innerException.GetType().IsAssignableFrom(typeof(System.Web.HttpException))) {
            return;
        }

        if(innerException is BusinessException) {
            context.Result = BuildErrorResult(exception);
            return;
        }

        //...other handler code
    }

    IHttpActionResult BuildErrorResult(BusinessException exception) { 
        //... your logic here 
    }
}

HttpConfiguration , , .

public static HttpConfiguration ReplaceExceptionHandler(this HttpConfiguration config) {
    var errorHandler = config.Services.GetExceptionHandler();
    if (!(errorHandler is WebApiExceptionHandler)) {
        var service = config.Services.GetService(typeof(WebApiExceptionHandler));
        config.Services.Replace(typeof(IExceptionHandler), service);
    }
    return config;
}

, , . ApiController

public class LinkBookingController : ApiController {
    private IBookingService bookingService;

    public LinkBookingController(IBookingService service) {
        bookingService = service;
    }

    [HttpPost]
    [Route("TnC")]
    public IHttpActionResult TnC(CustomViewModel myViewModel) {

        return Json(bookingService.TnC(myViewModel, User));

    }
}

IBookingService

public interface IBookingService {
    BookingModel TnC(CustomViewModel viewModel, IPrincipal user);
}

, ​​ Moq, .

[TestMethod]
[ExpectedException(typeof(BusinessException), "Not a valid Business Case")]
public void TnC_Should_Throw_BusinessException() {
    //Arrange
    var bookingService = new Mock<IBookingService>();

    var controller = new LinkBookingController(bookingService.Object);

    var viewModel  = new myViewModel
    {
        //...params
    };

    bookingService.Setup(_ => _.TnC(viewModel, It.IsAny<IPrincipal>())).Throws<BusinessException>()

    //Act
    var expectedResult = controller.TnC(viewModel);

    //Assert
    //...the ExpectedException attribute should assert if it was thrown
}

, , unit test , , .

, .

+2

Nkosi, _Internal, , .

, IInternalService ( ) _Internal. - , .

, ( " " ), unit test , , . , , , , ​​ Moq.

, .

+1

Source: https://habr.com/ru/post/1015932/


All Articles