У меня есть приложение mvc, и я работаю с объектами poco и пишу модульный тест. Проблема в том, что все мои тесты терпят неудачу, когда достигают этой строки кода Roles.IsUserInRole("someUser", "role"). Должен ли я реализовать новый интерфейс или репозиторий для ролей или...? Спасибо
Модульный тест (mvc) - проблема с ролями
Ответы (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);
Надеюсь это поможет.
Вы можете настроить пользовательский метод для проверки ролей, которые будут вести себя по-разному в тестах, но я предпочитаю, чтобы тесты настраивали контекст, который будет работать со стандартными методами.
Вы можете создать легкую оболочку с помощью 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());