Модульное тестирование Microsoft с поставщиком членства ASP.NET - PullRequest
1 голос
/ 19 октября 2011

Кто-нибудь еще разочарован встроенной структурой модульного тестирования ASP.NET? Проблема, с которой я сталкиваюсь, - это подключение и тестирование на провайдере членства для ASP.NET в приложении MVC3. Похоже, что соединение с базой данных не было установлено или существует другой набор правил, чем при нормальном запуске приложения. Вот два сценария.

1) Попытка найти существующего пользователя по имени:

Модульный тест -

    [TestMethod]
    public void RegisterTest()
    {
        AccountController target = new AccountController(); 
        RegisterModel model = new RegisterModel() { UserName = "existinguser", Email = "email@test.com", Password = "Password", ConfirmPassword = "Password" };
        actual = target.Register(model);
    }

Блок кода из AccountController -

            MembershipCreateStatus createStatus;
            MembershipUserCollection members = Membership.FindUsersByName(model.UserName);
            MembershipUser user = null;
            if (members.Count > 0)
                createStatus = MembershipCreateStatus.DuplicateUserName;

Результат - Когда я вхожу в этот код, массив members пуст, хотя я знаю, что этот пользователь находится в системе. Есть ли какая-нибудь хитрость для установления соединения с хранилищем членства в приложении модульного тестирования? Я попытался использовать атрибут источника данных, но безуспешно.

2) Попытка создать новую учетную запись: Модульный тест такой же, как и выше, однако я передаю нового пользователя, которого еще нет в системе. Когда я вхожу в контроллер и перехожу к следующей строке, он дает мне membersCreateStatus 'InvalidQuestion'. Это кажется странным, так как при запуске вживую у меня нет этой проблемы, и я могу создавать учетные записи с такой линией, как она.

user = Membership.CreateUser(model.UserName, model.Password, model.Email, string.Empty, string.Empty, true, null, out createStatus);

Заранее спасибо за помощь. Я действительно пытаюсь сделать этот тест первым методом, но он усложняет использование встроенной среды тестирования. Конечно, есть способ подключиться к БД для всех модульных тестов (не предоставляя подключения для каждого теста) и имитировать те же действия, что и в браузере.

Ответы [ 2 ]

3 голосов
/ 19 октября 2011

Когда вы запускаете свои модульные тесты, он будет эффективно работать как новое приложение и, следовательно, будет использовать свой собственный файл конфигурации - другими словами, не web.config, который использует ваше приложение MVC.Поэтому я думаю, что вам не хватает без дополнительной информации записи в файле app.config в вашем тестовом проекте для строки подключения к базе данных, в которой хранится информация о вашем членстве (может также отсутствовать app.config).

Если вы пытаетесь использовать подход TDD, вы должны писать модульные тесты, и если вам нужно подключиться к базе данных для выполнения модульных тестов, они, вероятно, являются интеграционными тестами, а не модульными тестами.Поскольку классы Membership используют статические методы, это усложняет ситуацию.Я бы порекомендовал обернуть функциональность членства в свою собственную службу соответствующим интерфейсом (например, IMembershipService), который затем может быть добавлен вашим контейнером IoC.Для целей ваших модульных тестов вы можете просто смоделировать созданный вами интерфейс IMembershipService без необходимости подключения к вашей базе данных.

2 голосов
/ 07 января 2012

У меня была такая же проблема.И да, похоже, мои модульные тесты больше похожи на интеграционные тесты, но мне просто нужно было протестировать контроллеры, и скорость не была проблемой на данном этапе проекта.Я в основном добавил всю конфигурацию sql memberbership и строку подключения из web.config проекта MVC 3, чтобы протестировать app.config проекта, и поставщик членства работал, когда выполнялись модульные тесты.Ниже приведен пример app.config моего тестового проекта.

<?xml version="1.0" encoding="utf-8"?>
<!-- 
    Note: Add entries to the App.config file for configuration settings
    that apply only to the Test project.
-->
<configuration>
  <appSettings></appSettings>
  <connectionStrings>
    <add name="ApplicationServices" connectionString="mySqlServer;initial catalog=mySqlMembershipDB;persist security info=True;user id=mySqlUser;password=mySqlPassword;" providerName="System.Data.SqlClient" />
  </connectionStrings>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.0.5.0" newVersion="4.0.5.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>

  <system.web>
    <membership defaultProvider="AspNetSqlMembershipProvider">
      <providers>
        <clear />
        <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="ApplicationServices" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="true" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />
      </providers>
    </membership>
    <profile defaultProvider="AspNetSqlProfileProvider">
      <providers>
        <clear />
        <add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="/" />
      </providers>
    </profile>
    <roleManager enabled="false" defaultProvider="AspNetSqlRoleProvider">
      <providers>
        <clear />
        <add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="ApplicationServices" applicationName="/" />
      </providers>
    </roleManager>
  </system.web>
</configuration>
...