Я использую пользовательский атрибут авторизации (явно плагиат из другого SO-ответа), но натолкнулся на препятствие, где я не могу найти способ его модульного тестирования. К сожалению, мне нужно выполнить модульное тестирование одновременно с тем, как я вызываю действие моего контроллера, поэтому я пытаюсь найти способ сделать внедрение зависимостей Ninject в модульном тесте.
Атрибут AuthorizeWhereIn:
public class AuthorizeWhereIn : AuthorizeAttribute
{
/// <summary>
/// Add the allowed roles to this property.
/// </summary>
public new HCIRoles Roles;
/// <summary>
/// Checks to see if the user is authenticated and has the
/// correct role to access a particular view.
/// </summary>
/// <param name="httpContext"></param>
/// <returns></returns>
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (httpContext == null)
throw new ArgumentNullException("httpContext");
// Make sure the user is authenticated.
if (!httpContext.User.Identity.IsAuthenticated)
return false;
// Get user's current roles
var roles = System.Web.Security.Roles.GetRolesForUser();
HCIRoles currentRoles = (HCIRoles)Enum.Parse(typeof(HCIRoles), string.Join(",", roles));
// Perform a bitwise operation to see if the user's role
// is in the passed in role values.
if (Roles != 0 && ((Roles & currentRoles) == 0))
return false;
return true;
}
}
Проблема заключается в вызове System.Web.Security.Roles.GetRolesForUser (), который недоступен в моем модульном тесте и который я хочу каким-либо образом смоделировать. Я могу абстрагировать этот вызов в отдельный интерфейс и использовать Ninject для внедрения его в веб-приложение, но не могу найти способ сделать то же самое в модульном тесте.
Так что, если я изменю атрибут на что-то вроде ниже
public class AuthorizeWhereIn : AuthorizeAttribute
{
[Inject]
IRoleService RoleService { get; set; }
...
}
и мой код модульного теста выглядит следующим образом:
[TestMethod()]
public void IndexTest()
{
var builder = new TestControllerBuilder();
var controller = builder.CreateController<UserController>(dataLayer.Object);
var invoker = new ActionInvoker<UserController>();
var mockMembershipService = new Mock<IMembershipService>();
mockMembershipService.Setup(x => x.GetAllUsers(It.IsAny<int>(), It.IsAny<int>(), out total)).Returns(new MembershipUserCollection());
controller.MembershipService = mockMembershipService.Object;
builder.InitializeController(controller);
invoker.InvokeAction(controller.ControllerContext, x => x.Index());
}
И тестируемый контроллер:
[AuthorizeWhereIn(Roles = HCIRoles.Admin)]
public class UserController : BaseController
{
public ActionResult Index()
{
return View();
}
}
У меня вопрос, как я могу внедрить зависимость RolseService в модульный тест, если у меня нет прямого доступа к атрибуту AuthroizeWhereIn?
Я прочитал и перечитал расширение Ninject Filter для MVC3 http://www.planetgeek.ch/2010/11/13/official-ninject-mvc-extension-gets-support-for-mvc3/, но не могу применить его к этому случаю.