C# Asp.net MVC集成测试与Web安全

C# Asp.net MVC集成测试与Web安全,c#,asp.net,asp.net-mvc,unit-testing,asp.net-mvc-4,C#,Asp.net,Asp.net Mvc,Unit Testing,Asp.net Mvc 4,我正在开发一个ASP.NETMVC4网站,我想测试一下。在我要测试的控制器中,我调用 WebSecurity.CreateUserAndAccount 关于这个调用,我有一些逻辑,我想测试一下。所以我测试了整个动作(在将来,我将不得不做不止一次) 这是我的测试 [TestMethod] public void RegisterUser() { // Arrange var controller = new UserC

我正在开发一个ASP.NETMVC4网站,我想测试一下。在我要测试的控制器中,我调用

WebSecurity.CreateUserAndAccount

关于这个调用,我有一些逻辑,我想测试一下。所以我测试了整个动作(在将来,我将不得不做不止一次)

这是我的测试

[TestMethod]
        public void RegisterUser()
        {
            // Arrange
            var controller = new UserController("TestConnection");

            // Act
            var user= new UserModel()
            {
                MailAddressTemp = "dummyuser@gmail.com",
                Password = "password",
                ConfirmPassword = "password",
                FirstName = "firstname",
                LastName = "lastname",
            };
            TestHelper.ValidateViewModel(user, controller);
            if (!controller.ModelState.IsValid)
                Assert.Inconclusive("Model should be valid!");
            controller.Register(user);
            using (var context = new PatientDbContext("TestConnection"))
            {
                var userProfile = context.UserProfiles.FirstOrDefault(x => x.MailAddress == "dummyuser@gmail.com");
                Assert.IsNotNull(userProfile);
                Assert.AreEqual("dummyuser@gmail.com", WebSecurity.CurrentUserName);
                Assert.IsTrue(WebSecurity.UserExists("dummyuser@gmail.com"));
                WebSecurity.Logout();
                var islogged = WebSecurity.Login("dummyuser@gmail.com", "password");
                Assert.IsTrue(islogged);
            }
        }
我的问题是,当我想使用

WebSecurity.CreateUserAndAccount

这是个例外

若要调用此方法,“Membership.Provider”属性必须是 “ExtendedMembershipProvider”的实例

我需要在将来的测试中使用WebSecurity。我来自WPF世界,在我的集成测试中,我能够启动一个应用程序容器并从单元测试解决方案中测试它。 在这里,当我运行测试时,web应用程序似乎没有启动,我不知道如何启动

我的问题是:

如何在测试解决方案中使用WebSecurity并解决异常

如何启动应用程序,以便像中一样加载所有对象 一个实时应用程序,并从单元中的代码测试我的操作 测试

我不想要浏览器。我想做一些像这样的事情

StartApp()
var result = MyController.Action(params)//My action uses WebSecurity for instance
Assert.IsTrue(something from result)
任何帮助都会有帮助!
谢谢大家!

您最好围绕WebSecurity类的静态方法创建decorator。您将能够模拟它并隔离控制器核心。例如:

public interface IWebSecurity
{
    bool CreateUserAndAccount(....);
}

public class MyWebSecurity: IWebSecurity
{
    public bool CreateUserAndAccount(...)
    {
        WebSecurity.CreateUserAndAccount(...);
    }
}
在测试代码中,您将能够执行(使用Moq测试框架):

var-webSecurity=newmock();
var controller=newusercontroller(“TestConnection”,webSecurity.Object);

我找到了部分解决方案。我需要在我的测试解决方案的app.config中添加这个

<system.web>
    <roleManager enabled="true" defaultProvider="SimpleRoleProvider">
      <providers>
        <clear />
        <add name="SimpleRoleProvider" type="WebMatrix.WebData.SimpleRoleProvider, WebMatrix.WebData" />
      </providers>
    </roleManager>
    <membership defaultProvider="SimpleMembershipProvider">
      <providers>
        <clear />
        <add name="SimpleMembershipProvider" type="WebMatrix.WebData.SimpleMembershipProvider, WebMatrix.WebData" />
      </providers>
    </membership>
    <sessionState mode="InProc" customProvider="DefaultSessionProvider">
      <providers>
        <add name="DefaultSessionProvider" type="System.Web.Providers.DefaultSessionStateProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" />
      </providers>
    </sessionState>
  </system.web>

您必须在测试项目中添加引用中的WebMatrix.webData和WebMtrix.Data,并将“Copy local”设置为true,但这不起作用,因为当我调用WebSecurity.CreateUserAndAccount时,我会根据此操作及其结果(外键等)在数据库中添加数据。代码的其余部分保持不变,您只需修改对WebSecurity.CreateUserAndAccount的调用。当然,您可以模拟此函数的输出。因此,您将测试控制器代码,而不是包括成员资格提供程序代码在内的所有代码。这是否违背了“集成”测试的理念。来自:“构建测试用例是为了测试组件中的所有组件是否正确交互,例如跨过程调用或进程激活,这是在测试单个模块(即单元测试)之后完成的。”。因此,您可能希望执行预期组件,而不是模拟组件。
<system.web>
    <roleManager enabled="true" defaultProvider="SimpleRoleProvider">
      <providers>
        <clear />
        <add name="SimpleRoleProvider" type="WebMatrix.WebData.SimpleRoleProvider, WebMatrix.WebData" />
      </providers>
    </roleManager>
    <membership defaultProvider="SimpleMembershipProvider">
      <providers>
        <clear />
        <add name="SimpleMembershipProvider" type="WebMatrix.WebData.SimpleMembershipProvider, WebMatrix.WebData" />
      </providers>
    </membership>
    <sessionState mode="InProc" customProvider="DefaultSessionProvider">
      <providers>
        <add name="DefaultSessionProvider" type="System.Web.Providers.DefaultSessionStateProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" />
      </providers>
    </sessionState>
  </system.web>
    WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "MailAddress", autoCreateTables: true);