ЖАНРЫ

Шрифт:

public AccountMembershipService

: this(null)

{

}

public AccountMembershipService(MembershipProvider provider)

{

_provider = provider ?? Membership.Provider;

}

public int MinPasswordLength

{

get

{

return _provider.MinRequiredPasswordLength;

}

}

public bool ValidateUser(string userName, string password)

{

return _provider.ValidateUser(userName, password);

}

public MembershipCreateStatus CreateUser(string userName,

string password, string email)

{

MembershipCreateStatus status;

_provider.CreateUser(userName, password,

email, null, null, true, null, out status);

return status;

}

public bool ChangePassword(string userName,

string oldPassword, string newPassword)

{

MembershipUser currentUser = _provider.GetUser(

userName, true);

return currentUser.ChangePassword(oldPassword, newPassword);

}

}

Выделение

обертки над службами ASP.NET позволяет не только получить возможность простого тестирования, но и заменять реализацию в процессе развития приложения. Например, при замене стандартного провайдера Membership на собственную реализацию или изменение провайдера авторизации для поддержки сертификатов, или Windows-аутентификация. Однако в целях тестирования этот подход просто незаменим.

Во время работы веб-приложения, созданного из шаблона, используется стандартная фабрика контроллеров, не передающая дополнительных параметров конструктору класса Accountcontroller, в тестовом же окружении используется имитация — код классов, имитирующих бурную деятельность. Пример классов, реализующих подход имитации, приведен в листинге 8.4.

Листинг 8.4. Классы для имитации в условиях тестирования

public class MockFormsAuthenticationService :

IFormsAuthentication

{

public void SignIn(string userName,

bool createPersistentcookie) { }

public void SignOut { }

}

public class MockHttpContext : HttpContextBase

{

private IPrincipal _user;

public override IPrincipal User

{

get

{

if (_user == null)

{

_user = new MockPrincipal;

}

return _user;

}

set

{

_user = value;

}

}

}

Аналогично коду, приведенному в листинге 8.4, строятся остальные классы, используемые для тестирования. Основной принцип их создания состоит в том, чтобы развязать процесс тестирования с реальным функционалом — вместо работы с базами данных не делать ничего, либо возвращать стандартные значения, используемые для тестирования, и т. п.

Пример использования имитирующих классов в целях тестирования

приведен в листинге 8.5. Процесс подготовки объектов выделен в отдельный метод GetAccountController .

Листинг 8.5. Несколько методов для тестирования AccountController

private static AccountController GetAccountController

{

IFormsAuthentication formsAuth = new

MockFormsAuthenticationService;

MembershipProvider membershipProvider = new MockMembershipProvider;

AccountMembershipService membershipService = new

AccountMembershipService(membershipProvider);

AccountController controller = new

AccountController(formsAuth, membershipService);

ControllerContext controllerContext = new

ControllerContext(new MockHttpContext,

new RouteData,

controller);

controller.ControllerContext = controllerContext;

return controller;

}

[Test]

public void RegisterPostReturnsViewIfPasswordIsNull

{

AccountController controller = GetAccountController;

ViewResult result = (ViewResult)controller.Register("username",

"email", null, null);

Assert.AreEqual(6, result.ViewData["PasswordLength"]);

Assert.AreEqual(

"You must specify a password of 6 or more characters.",

result.ViewData.ModelState["password"].Errors[0].ErrorMessage);

}

[Test]

public void

RegisterPostReturnsViewIfNewPasswordDoesNotMatchConfirmPassword

{

AccountController controller = GetAccountController;

ViewResult result = (ViewResult)controller.Register("username",

"email", "password", "password2");

Assert.AreEqual (6, result.ViewData["PassworcLLength"] );

Assert.AreEqual(

"The new password and confirmation password do not match.",

result.ViewData.ModelState["_FORM"].Errors[0].ErrorMessage);

}

[Test]

public void RegisterPostReturnsViewIfPasswordIsTooShort

{

AccountController controller = GetAccountController;

ViewResult result = (ViewResult)controller.Register("username",

"email", "12345", "12345");

Assert.AreEqual(6, result.ViewData["PasswordLength"]);

Assert.AreEqual(

"You must specify a password of 6 or more characters.",

result.ViewData.ModelState["password"].Errors[0].ErrorMessage);

}

[Test]

public void RegisterPostReturnsViewIfRegistrationFails

{

AccountController controller = GetAccountController;

ViewResult result = (ViewResult)controller.Register("someUser",

"DuplicateUserName" /* error */, "badPass", "badPass");

Assert.AreEqual(6, result.ViewData["PasswordLength"]);

Поделиться с друзьями: