Модульный тест (mvc) - проблема с ролями

У меня есть приложение mvc, и я работаю с объектами poco и пишу модульный тест. Проблема в том, что все мои тесты терпят неудачу, когда достигают этой строки кода Roles.IsUserInRole("someUser", "role"). Должен ли я реализовать новый интерфейс или репозиторий для ролей или...? Спасибо


person Cipiripi    schedule 04.01.2011    source источник
comment
Здесь недостаточно информации, чтобы ответить на ваш вопрос. Пожалуйста, рассмотрите возможность пересмотра/добавления кода/добавления деталей к вашему вопросу.   -  person Kendrick    schedule 04.01.2011
comment
Почему они терпят неудачу? Можете ли вы опубликовать подробности об исключении и какую структуру вы используете? Большинство фреймворков используют типы исключений для сбоя, поэтому это может быть сбой или исключение, вызванное изоляцией теста.   -  person StuperUser    schedule 04.01.2011
comment
Я реализовал ролевое тестирование в контроллере, аналогичном нажмите один раз   -  person k3b    schedule 04.01.2011
comment
Это сообщение об ошибке: System.Configuration.Provider.ProviderException: функция диспетчера ролей не включена.   -  person Cipiripi    schedule 05.01.2011


Ответы (3)


У меня была такая же проблема при попытке смоделировать функциональность Roles.IsUserInRole в моих закодированных модульных тестах. Мое решение состояло в том, чтобы создать новый класс с именем RoleProvider и интерфейс с методом IsUserInRole, который затем вызывал System.Web.Security.Roles.IsUserInRole:

public class RoleProvider: IRoleProvider
{
    public bool IsUserInRole(IPrincipal userPrincipal)
    {
        return System.Web.Security.Roles.IsUserInRole(userPrincipal.Identity.Name, "User");
    }
}

Затем в своем коде я вызываю метод RoleProvider IsUserInRole. Поскольку у вас есть интерфейс, вы можете имитировать IRoleProvider в своих тестах, показанный здесь пример использует Rhino Mocks:

var roleProvider = MockRepository.GenerateStub<IRoleProvider>();
roleProvider.Expect(rp => rp.IsUserInRole(userPrincipal)).Return(true);

Надеюсь это поможет.

person JayneT    schedule 04.01.2011
comment
Это очень хорошо для тестируемости. Немного раздражает, что моим контроллерам теперь нужен экземпляр RoleProvider. Может закончиться созданием базового класса контроллера, в котором это встроено (наряду с некоторыми другими общими свойствами/полями). Спасибо за предложение! - person Killnine; 25.09.2012

Вы можете настроить пользовательский метод для проверки ролей, которые будут вести себя по-разному в тестах, но я предпочитаю, чтобы тесты настраивали контекст, который будет работать со стандартными методами.

http://stephenwalther.com/blog/archive/2008/07/01/asp-net-mvc-tip-12-faking-the-controller-context.aspx

person Tom Clarkson    schedule 05.01.2011

Вы можете создать легкую оболочку с помощью Predicate/Func.

public static Predicate<string> IsUserInRole = role => Roles.IsUserInRole(role);

Затем используйте IsUserInRole() вместо Roles.IsUserInRole(). Во время выполнения вы получаете такое же поведение. Но во время тестирования вы можете переопределить функцию, чтобы она не обращалась к RoleProvider.

MyClass.IsUserInRole = role => true;

Если вы предпочитаете не иметь общедоступной статики, вы можете внедрить предикат через свой конструктор и сохранить его как частный только для чтения.

class MyClass
{    
    private readonly Predicate<string> IsUserInRole;
    MyClass(Predicate<string> roleChecker) { this.IsUserInRole = roleChecker }
    MyClass() : this(role => Roles.IsUserInRole(role)) { }
}

Если вы используете Moq, вы можете вернуть макет, а затем контролировать возвращаемое значение и/или проверить, был ли вызван метод. И проверьте, какое значение параметра было отправлено в Predicate.

Mock<Predicate<string>> mockRoleChecker = new Mock<Predicate<string>>();
var cut = new MyClass(mockRoleChecker.Object);
var expectedRole = "Admin";
mockRoleChecker.SetReturnsDefault<bool>(true);  // if not specified will return false which is default(bool)

cut.MyMethod();

mockRoleChecker.Verify(x => x(expectedRole), Times.Once());
person Sean B    schedule 25.02.2015