2

还有其他人对内置的 ASP.NET 单元测试框架感到沮丧吗?我遇到的问题是在 MVC3 应用程序中针对 ASP.NET 的成员资格提供程序进行连接和测试。看起来数据库连接尚未建立,或者当我正常运行应用程序时存在一组不同的规则。这是两种情况。

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;

结果 - 当我进入此代码时,即使我知道该用户在系统中,成员数组也是空的。在单元测试应用程序中建立与会员商店的连接是否有一些技巧?我尝试使用 datasource 属性但没有成功。

2)尝试创建一个新的会员帐户:单元测试与上面相同,但是我传递了一个尚未在系统中的新用户。当我进入控制器并进入下一行时,它给了我一个“无效问题”的成员资格创建状态。这看起来很奇怪,因为在运行此直播时我没有这个问题,并且可以按原样创建帐户。

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

在此先感谢您的帮助。我真的很想先做这个测试方法,但是使用内置的测试框架使它变得更加困难。当然,有一种方法可以连接到所有单元测试的数据库(不为每个测试提供连接)并模拟我通过浏览器执行的相同操作。

4

2 回答 2

3

当您运行单元测试时,它将有效地作为一个新应用程序运行,因此将使用它自己的配置文件 - 换句话说,不是您的 MVC 应用程序使用的 web.config。因此,如果没有更多信息,我猜您缺少的是测试项目中 app.config 文件中的一个条目,用于保存您的成员信息的数据库的连接字符串(您也可能缺少 app.config)。

如果您尝试采用 TDD 方法,您应该编写单元测试,并且如果您需要连接到数据库以运行单元测试,那么它们可能是集成测试而不是单元测试。因为 Membership 类使用静态方法,这使得事情变得困难。我建议将会员功能包装在它自己的服务中,并带有相应的接口(例如 IMembershipService),然后可以由您的 IoC 容器注入。出于单元测试的目的,您可以简单地模拟您创建的 IMembershipService 接口,而无需连接到您的数据库。

于 2011-10-19T12:20:51.333 回答
2

我有同样的问题。是的,看起来我的单元测试更像是集成测试,但我只需要测试控制器,并且在项目的这一点上速度不是问题。我基本上将 MVC 3 项目的 web.config 中的所有 sql 成员资格配置和连接字符串添加到测试项目的 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>
于 2012-01-07T16:38:38.197 回答