【问题标题】:NUnit Test for ActionResult which checks user roles用于检查用户角色的 ActionResult 的 NUnit 测试
【发布时间】:2016-02-19 17:31:17
【问题描述】:

我目前是 ASPNET MVC 框架的新手,我想使用 NUnit 进行一些单元测试,但遇到了困难。

我的问题是我有一个控制器,并且大多数 ActionResults 方法都在其中检查了当前登录用户是否属于某些角色,现在我的问题是如何使用 NUnit 登录所以那些ActionResults 测试可以进行,否则返回nullexception

以下是Index() 方法的部分代码,让您大致了解一下情况。您能否指出我可以在其中测试什么样的东西?

public ActionResult Index()
{
      IEnumerable<Colour> colours = null;

      if (isUserAdmin())
      {
          colours = db.Colours;
      }
      else
      {
          string userId = User.Identity.GetUserId();
          IEnumerable<string> userRoleIds = db.Users.Find(userId).Roles.Select(x => x.Id);
          colours = db.ColourRoles.Where(x => userRoleIds.Contains(x.RoleId)).Select(y => y.Colour).Distinct();
      }

      ViewData["Colours"] = colours;            
      return View();
} 

提前谢谢你。

【问题讨论】:

  • 你在使用moq这样的模拟框架吗?在您在测试中调用 Index 方法之前,您可以使用模拟用户/身份模拟 httpcontext 和 controllercontext。但是,这可能会也可能不会完全解决您的情况,具体取决于您是注入 db 还是需要做一些事情才能使该调用正常工作。
  • @stephen.vakil 我根本没有使用任何模拟框架。我认为这可能是一个正确的混乱。你还有什么可以建议我的吗?
  • 将控制器中的代码重构为接口,并在测试中使用不同的实现。

标签: asp.net .net asp.net-mvc unit-testing nunit


【解决方案1】:

对您的控制器进行一些假设并使用本演练Walkthrough: Using TDD with ASP.NET MVC 中的一个想法,我认为您可以试试这个

[TestClass]
public class ControllerUnitTest {

    [TestMethod]
    public void ControllerIndexTest() {
        // Arrange
        var username = "[Test_Username_Here]";
        string[] roles = new[] { "FakeRoleId1", "FakeRoleId2" };
        var controller = new CollorsController(new FakeDbContext());
        controller.ControllerContext = new ControllerContext() {
            Controller = controller,
            RequestContext = new RequestContext(new MockHttpContext(username, roles), new RouteData())
        };

        // Act
        var actionResult = controller.Index();
        var viewResult = actionResult as ViewResult;

        // Assert
        Assert.IsNotNull(viewResult);
        Assert.IsTrue(viewResult.ViewData.ContainsKey("Colours"));
    }

    private class MockHttpContext : HttpContextBase {
        private readonly IPrincipal user;

        public MockHttpContext(string username, string[] roles = null) {
           var identity = new GenericIdentity(username, string.Empty);
           var principal = new GenericPrincipal(identity, roles ?? new string[] { });
           user = principal;
        }

        public override IPrincipal User {
            get {
                return user;
            }
            set {
                base.User = value;
            }
        }
    }
}    

【讨论】:

    【解决方案2】:

    您可以使用Typemock Isolator 轻松模拟 HttpContext:

    var username = "[Test_Username_Here]";
    string[] roles = new[] { "FakeRoleId1", "FakeRoleId2" };
    var fake = Isolate.Fake.AllInstances<HttpContextBase>();
    var user = new ClaimsPrincipal(new GenericPrincipal(username, roles ?? new string[] { }));
    Isolate.WhenCalled(() => fake.User).WillReturn(user);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-10-16
      • 2020-08-04
      • 2011-01-20
      • 2011-11-05
      • 1970-01-01
      • 1970-01-01
      • 2012-04-18
      • 2016-08-28
      相关资源
      最近更新 更多