【问题标题】:Integration testing an MVC application without the pain of UI automation无需 UI 自动化的痛苦集成测试 MVC 应用程序
【发布时间】:2013-01-26 20:49:22
【问题描述】:

我正在开始开发一个新的 MVC 应用程序,该应用程序将主要使用 TDD 编写。我想添加一些集成测试以确保完全连接的应用程序(我将 StructureMap 用于 IOC,NHibernate 用于持久性)按预期工作。

虽然我打算使用 Selenium 编写一些功能性冒烟测试,但出于可维护性的原因,我宁愿通过使用良好的旧 C# 在我的控制器上直接调用操作来完成大部分集成测试。

关于如何实现这一点的指导令人惊讶地少,所以我尝试了一个攻击计划

  1. 将所有引导代码从 Global.asax 中提取到单独的类中
  2. 尝试利用 MvcContrib-TestHelper 或类似工具来创建 ASP.NET 依赖项(上下文、请求等)

我已经完成了第 1 步,但真的不知道如何进行第 2 步。任何指导将不胜感激。

public class Bootstrapper
{              
    public static void Bootstrap()
    {
        DependencyResolverInitializer.Initialize();
        FilterConfig.RegisterFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        ModelBinders.Binders.DefaultBinder = new SharpModelBinder();
    }           
}

public class DependencyResolverInitializer
{
    public static Container Initialize()
    {
        var container = new Container();
        container.Configure(x => x.Scan(y =>
        {
            y.Assembly(typeof(Webmin.UI.FilterConfig).Assembly);
            y.WithDefaultConventions();
            y.LookForRegistries();

        }));

        DependencyResolver.SetResolver(new StructureMapDependencyResolver(container));
        return container;
    }
}

public class StructureMapDependencyResolver : IDependencyResolver
{
    private readonly IContainer _container;

    public StructureMapDependencyResolver(IContainer container)
    {
        _container = container;
    }

    public object GetService(Type serviceType)
    {
        if (serviceType.IsAbstract || serviceType.IsInterface) {
            return _container.TryGetInstance(serviceType);
        }
        return _container.GetInstance(serviceType);
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        return _container.GetAllInstances(serviceType).Cast<object>();
    }
}

【问题讨论】:

    标签: asp.net-mvc integration-testing mvccontrib


    【解决方案1】:

    如果您想在不通过 UI 的情况下对 ASP.NET MVC 应用程序进行自动端到端测试,一种好方法是以编程方式将 HTTP 请求发送到不同的URL 并在之后断言系统的状态。

    您的集成测试基本上如下所示:

    1. 安排:启动一个网络服务器来托管被测网络应用程序
    2. Act:向特定 URL 发送 HTTP 请求,该请求将由控制器操作处理
    3. 断言:验证系统状态(例如,查找特定的数据库记录),或验证响应的内容(例如,在返回的 HTML 中查找特定字符串)

    您可以使用CassiniDevin-process Web 服务器中轻松托管 ASP.NET Web 应用程序。此外,以编程方式发送 HTTP 请求的一种便捷方法是使用 Microsoft ASP.NET Web API Client Libraries

    这是一个例子:

    [TestFixture]
    public class When_retrieving_a_customer
    {
        private CassiniDevServer server;
        private HttpClient client;
    
        [SetUp]        
        public void Init()
        {
            // Arrange
            server = new CassiniDevServer();
            server.StartServer("..\relative\path\to\webapp", 80, "/", "localhost");
            client = new HttpClient { BaseAddress = "http://localhost" };
        }
    
        [TearDown]
        public void Cleanup()
        {
            server.StopServer();
            server.Dispose();
        }
    
        [Test]
        public void Should_return_a_view_containing_the_specified_customer_id()
        {
            // Act
            var response = client.GetAsync("customers/123").Result;
    
            // Assert
            Assert.Contains("123", response.Content.ReadAsStringAsync().Result);
        }
    }
    

    如果您正在寻找该技术的更完整示例,您可以在我的sample MVC 4 web application 中找到它,我在automated acceptance tests 的上下文中对其进行了演示。

    【讨论】:

      猜你喜欢
      • 2011-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-10
      • 2010-11-23
      • 2015-08-15
      相关资源
      最近更新 更多