2016-02-19 26 views
1

我目前是ASPNET MVC框架的新手,我想用NUnit做一些单元测试,但我遇到了困难。NUnit测试用于检查用户角色的ActionResult

我的问题是,我有一个控制器和大部分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(); 
} 

在此先感谢您。

+0

您是否使用了嘲笑框架如moq?在测试中调用'Index'方法之前,可以用模拟用户/标识模拟httpcontext和controllercontext。但是,这可能会或可能不会完全解决您的情况,具体取决于您是在注入'db'还是需要执行某些操作才能使该呼叫生效。 –

+0

@ stephen.vakil我根本没有使用任何模拟框架。我认为这可能是一个正确的混乱。还有什么可以暗示我吗? – Jordan

+0

将控制器中的代码重构为接口,并在测试中使用不同的实现。 –

回答

0

使你的控制器的一些假设,并利用此演练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; 
      } 
     } 
    } 
}  
0

您可以轻松地嘲笑的HttpContext与Typemock Isolator

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);