ASP.NET Core对Controller进行单元测试的完整步骤

2020-06-19 10:59:26王旭

测试用例:

    [TestMethod()]
    public async Task LoginTest1()
    {
      var authenticationService = new Mock<IAuthenticationService>();
      //设置AuthenticateAsync为success
      authenticationService.Setup(s => s.AuthenticateAsync(It.IsAny<HttpContext>(), It.IsAny<string>()))
        .ReturnsAsync(AuthenticateResult.Success(new AuthenticationTicket(new System.Security.Claims.ClaimsPrincipal(), "")));
      var sp = new Mock<IServiceProvider>();
      sp.Setup(s => s.GetService(typeof(IAuthenticationService)))
        .Returns(() => {
          return authenticationService.Object;
        });

      var ctrl = new AccountController();
      ctrl.ControllerContext = new ControllerContext();
      ctrl.ControllerContext.HttpContext = new DefaultHttpContext();
      ctrl.ControllerContext.HttpContext.RequestServices = sp.Object;

      var act = await ctrl.Login();
      Assert.IsNotNull(act);
      Assert.IsInstanceOfType(act, typeof(RedirectResult));
      var rd = act as RedirectResult;
      Assert.AreEqual("/home", rd.Url);
      //设置AuthenticateAsync为fail
      authenticationService.Setup(s => s.AuthenticateAsync(It.IsAny<HttpContext>(), It.IsAny<string>()))
        .ReturnsAsync(AuthenticateResult.Fail(""));

      act = await ctrl.Login();
      Assert.IsNotNull(act);
      Assert.IsInstanceOfType(act, typeof(RedirectResult));
      rd = act as RedirectResult;
      Assert.AreEqual("/login", rd.Url);

    }

Filter进行测试

我们写Controller的时候往往需要配合很多Filter使用,所以Filter的测试也很重要。下面演示下如何对Fitler进行测试。

  public class MyFilter: ActionFilterAttribute
  {
    public override void OnActionExecuting(ActionExecutingContext context)
    {
      if (context.HttpContext.Request.Path.Value.Contains("/abc/"))
      {
        context.Result = new ContentResult() {
          Content = "拒绝访问"
        };
      }

      base.OnActionExecuting(context);
    }
  }

对Filter的测试最主要的是模拟ActionExecutingContext参数,以及其中的HttpContext等,然后对预期进行Assert。

    [TestMethod()]
    public void OnActionExecutingTest()
    {
      var filter = new MyFilter();
      var actContext = new ActionContext(new DefaultHttpContext(),new RouteData(), new ActionDescriptor());
      actContext.HttpContext.Request.Path = "/abc/123";
      var listFilters = new List<IFilterMetadata>();
      var argDict = new Dictionary<string, object>();
      var actExContext = new ActionExecutingContext(
        actContext ,
        listFilters ,
        argDict ,
        new AccountController()
        );
       filter.OnActionExecuting(actExContext);

      Assert.IsNotNull(actExContext.Result);
      Assert.IsInstanceOfType(actExContext.Result, typeof(ContentResult));
      var cr = actExContext.Result as ContentResult;
      Assert.AreEqual("拒绝访问", cr.Content);

      actContext = new ActionContext(new DefaultHttpContext(), new RouteData(), new ActionDescriptor());
      actContext.HttpContext.Request.Path = "/1/123";
      listFilters = new List<IFilterMetadata>();
      argDict = new Dictionary<string, object>();
      actExContext = new ActionExecutingContext(
        actContext,
        listFilters,
        argDict,
        new AccountController()
        );
      filter.OnActionExecuting(actExContext);
      Assert.IsNull(actExContext.Result);
    }