如何在 MoQ WebAPI 中抛出和获取异常对象

How to throw and get the exception object in MoQ WebAPI

我有一个启用了 OData 的 WebAPI,其中包含

  1. TestController:它包含一个自定义操作方法。
  2. WebApiExceptionHandler:WebApi 中的自定义异常处理程序, 注册于 WebApiConfig.cs.
  3. ITestManager:接口
  4. TestManager:Class 实施 ITestManager。这个 class 句柄 数据的所有业务逻辑。 WebAPI 控制器 TestController 有一个调用此 class.

    的函数

    此外,还有一个 TestWebAPI 项目,它使用 MoQ 框架进行测试。 TestMethod "Test_UpdatePackageVendorOnException__Success" 使用 MoQ 设置在 UpdateTestQuantity 方法中抛出异常。但是我在调​​试这个测试方法的时候,抛出异常的时候,调试器并没有指向WebApiExceptionHandlerclass。理想情况下,API 中发生的所有异常都在 WebApiExceptionHandler class

  5. 中处理

我面临的问题是,在我的测试方法中,我想在 WebApiExceptionHandler 返回的异常对象上测试一些东西。但是由于控件永远不会进入 WebApiExceptionHandler,所以我不能那样做。

如何修改代码以便在 TestMethod 中测试 WebApiExceptionHandler 返回的自定义对象。

网页API代码:

    public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.Services.Replace(typeof(IExceptionHandler), new WebApiExceptionHandler());

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        config.Routes.MapHttpRoute(
          name: "DefaultApiGetParam",
          routeTemplate: "api/{controller}/{key}/{count}",
          defaults: new { key = RouteParameter.Optional, count = RouteParameter.Optional }
        );
    }
}

public class WebApiExceptionHandler : ExceptionHandler
{
    public WebApiExceptionHandler()
    {
    }
    public override void Handle(ExceptionHandlerContext context)
    {
        try
        {
            var objCustomException = new CustomException(context.Exception);
            context.Result = new ResponseMessageResult(context.Request.CreateResponse(HttpStatusCode.InternalServerError, objCustomException);
        }
        catch (Exception)
        {
            base.Handle(context);
        }
    }

    public override bool ShouldHandle(ExceptionHandlerContext context)
    {
        return true;
    }
}


public interface ITestManager
{
    bool UpdateTestQuantity();

}

public class TestManager : ITestManager
{
    public TestManager()
    {
    }


    public bool UpdateTestQuantity()
    {
        //Custom Logic
        return true;
    }
}

public class TestController : ODataController
{
    ITestManager testManager;

    public TestController()
    {
        testManager = new TestManager();
    }

    public TestController(ITestManager iTestManager)
    {
        testManager = iTestManager;
    }

    public IHttpActionResult UpdateTestQuantity(ODataActionParameters param)
    {
        bool result = testManager.UpdateTestQuantity();
        return Ok();
    }
}

WebApiTest 项目

[TestClass]
public class TestControllerTest
{

    Mock<ITestManager> iTestManagerMock;
    TestController objTestController;

    [TestInitialize]
    public void Setup()
    {
        iTestManagerMock = new Mock<ITestManager>();
    }

    [TestMethod]
    [ExpectedException(typeof(Exception), AllowDerivedTypes = true)]
    public void Test_UpdateTestQuantityOnException__Success()
    {
        iTestManagerMock.Setup(i => i.UpdateTestQuantity().Throws(new Exception());
        objTestController = new TestController(iTestManagerMock.Object);
        var objODataActionParameters = new ODataActionParameters();
        objTestController.Request = new HttpRequestMessage();
        objTestController.Configuration = new HttpConfiguration();
        IHttpActionResult objIHttpActionResult = objTestController.UpdateTestQuantity(objODataActionParameters);

        //Problem Area
        //Control never reaches here after the exception is thrown  
        //Want to check some property of exception object returned via Exception WebApiExceptionHandler 
    }

    [TestCleanup]
    public void Clean()
    {
        iTestManagerMock = null;
    }
}

删除 [ExpectedException] 测试方法属性(这违反了 AAA principle) and rewrite the assert section of your test to use the Assert.Throws NUnit 方法。