4

我正在开始开发一个主要使用 TDD 编写的新 MVC 应用程序。我想添加一些集成测试以确保完全连接的应用程序(我将 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>();
    }
}
4

1 回答 1

5

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

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

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

您可以使用CassiniDev在进程内Web 服务器中轻松托管 ASP.NET Web 应用程序。此外,以编程方式发送 HTTP 请求的一种方便方法是使用Microsoft ASP.NET Web API 客户端库

这是一个例子:

[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);
    }
}

如果您正在寻找该技术的更完整示例,您可以在我的示例 MVC 4 Web 应用程序中找到它,我在编写自动化验收测试的上下文中对其进行了演示。

于 2013-02-12T09:59:58.770 回答