集成测试MVC应用程序,没有UI自动化的痛苦

时间:2013-02-11 17:26:14

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

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

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

关于人们如何实现这一目标的指导令人惊讶,因此我对攻击计划进行了抨击

  1. 将所有引导代码从Global.asax中拉出并放入单独的类
  2. 尝试利用MvcContrib-TestHelper或类似方法创建ASP.NET依赖项(上下文,请求等)
  3. 我已经完成了第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>();
        }
    }
    

1 个答案:

答案 0 :(得分:5)

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

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

  1. 排列:启动Web服务器以托管正在测试的Web应用程序
  2. 行动:向特定网址发送HTTP请求,该网址将由控制器操作处理
  3. 断言:验证系统的状态(例如查找特定的数据库记录),或验证响应的内容(例如,在返回的HTML中查找特定字符串)
  4. 您可以使用CassiniDev进程内 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的背景下展示了它。