【问题标题】:Specflow and HttpSelfHostServerSpecflow 和 HttpSelfHostServer
【发布时间】:2013-08-13 14:25:10
【问题描述】:

我创建了一个自托管的 ASP.NET Web API 实现,并希望它在 SpecFlow 测试中运行。

所以在我的规格中,我有一个步骤来启动 selfhostserver:

var config = new HttpSelfHostConfiguration("http://localhost:9000");    
var server = new HttpSelfHostServer(config);

 _apiApplication.Start(); //IoC, route-configs etc.

server.OpenAsync().Wait();

var httpClient = new HttpClient();
var response = httpClient.GetAsync(fetchUrl).Result;

GetAsync 调用发生的异常:

Exception : System.AggregateException: One or more errors occurred. 
---> System.Net.Http.HttpRequestException: An error occurred while sending the request. 
---> System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a receive. 
---> System.IO.IOException: Unable to read data from the transport connection

测试运行似乎阻止了在规范完成之前对自托管 API 的任何调用。调试时,我可以调用 url - 但它会挂起,直到测试运行完成。完成后,它会给出很好的响应。

我还创建了一个控制台应用程序,它可以完美地运行此代码,并给出预期的结果。

任何拥有通过 HttpSelfHostServer 进行测试的 SpecFlow 测试套件的人,或者知道如何让自托管 WebApi 在 SpecFlow 套件中工作?

【问题讨论】:

  • 你什么时候启动它?它在给定的绑定中吗?
  • @Alski ,我试过把它放几个 SpecFlow 段。在 BeforeScenario 中,在 Given-step 中,然后使用 HttpClient 进行调用,或者只是在单个 When 中将其全部混合。在所有情况下都有相同的效果:/ 我似乎在 MSTest 运行中也得到了相同的效果,所以可能不仅仅是 SpecFlow。

标签: c# asp.net-mvc-4 asp.net-web-api mstest specflow


【解决方案1】:

我已经设法为 WCF 服务而不是 Web 应用程序执行此操作,但理论上它应该是相同的。

一个大问题是释放服务器上的端口,因此我为每次运行分配不同的端口,如下

private static int FreeTcpPort()
    {
        var l = new TcpListener(IPAddress.Loopback, 0);
        l.Start();
        int port = ((IPEndPoint)l.LocalEndpoint).Port;
        l.Stop();
        return port;
    }


    [Given(@"a WCF Endpoint")]
    public void GivenAWCFEndpoint()
    {
        //The client 
        RemoteServerController.DefaultPort = FreeTcpPort();

        //The server
        var wcfListener = new ListenerServiceWCF
            {
                BindingMode = BindingMode.TCP,
                Uri = new Uri(string.Format("net.tcp://localhost:{0}",
                     RemoteServerController.DefaultPort))
            };
        //The wrapped host is quite a bit of generic code in our common libraries
        WrappedHostServices.Add(wcfListener);
        WrappedHostServices.Start();
    }

即便如此,我仍然偶尔会遇到测试失败,因此,如果您可以减少运行代码所需的基础架构数量,那么我建议您在没有它的情况下运行大部分测试,并且只运行几个以确保它正常工作。

【讨论】:

    【解决方案2】:

    自从被问到这个问题以来,我一直在关注这个问题,因为我们遇到了完全相同的问题。

    目前我们正在调用 IIS express 来托管我们的 WebAPI 服务,在 specFlow 运行开始时启动它们并在最后使用 IIS 自动化 nuget 包 https://github.com/ElemarJR/IISExpress.Automation 处理它们

    我们在使用 MS Test runner 时也遇到了问题,但使用 ReSharper,它们目前似乎都可以正常运行。

    如果其他人有什么可以贡献的,我也很感兴趣

    【讨论】:

    • 嗨@Kerplosh。对我们来说,问题出在我们注册的全局过滤器上。在过滤器中,我们尝试访问 HttpContext.Current,这会在 SelfHosted 模式下引发 NullReferenceException。请检查 HttpContext.Current 的任何自定义属性和过滤器,并添加对没有 HttpContext 的支持。也可能是您的问题的根源。
    • @John 感谢您的回复。我们还有一些其他有趣的挑战需要克服 - 但会留意对 HttpContext 的引用。
    【解决方案3】:

    我相信您忘记了 ReadAsync() 上的 Wait() 语句。试试下面的:

        var config = new HttpSelfHostConfiguration("http://localhost:9000");    
        var server = new HttpSelfHostServer(config);
    
         _apiApplication.Start(); //IoC, route-configs etc.
    
        server.OpenAsync().Wait();
    
        var httpClient = new HttpClient();
        var requestTask = httpClient.GetAsync(fetchUrl);
        requestTask.Wait();
        var response = requestTask.Result;
    

    这应该可以防止您的代码立即退出,这可能就是您收到异常的原因。

    【讨论】:

      猜你喜欢
      • 2012-07-06
      • 1970-01-01
      • 2012-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-12
      • 1970-01-01
      相关资源
      最近更新 更多