【问题标题】:Unit testing Asp.Net WebApi: how to test correct routing of a method with [FromUri] parameters单元测试 Asp.Net WebApi:如何使用 [FromUri] 参数测试方法的正确路由
【发布时间】:2016-03-06 10:38:47
【问题描述】:

我想测试这个控制器:

[HttpGet]
public IList<Notification> GetNotificationsByCustomerAndId([FromUri] string[] name, [FromUri] int[] lastNotificationID)         
{
    return _storage.GetNotifications(name, lastNotificationID, _topX);
}

特别是,在此方法中,我想测试传入输入以形成请求 Url 的数组是否与进入routeData.Values 的数组相同。如果对于单值参数(不是数组),它可以工作,但不适用于数组。如果我调试Values,我只会看到controller 和action。

[TestMethod]
public void GetNotificationsByCustomerAndId_ArrayOverload_Should_Match_InputParameter_name()
{
    string[] _testName = new string[] { _testCustomer, _testCustomerBis };

    string Url = string.Format(
           "http://www.testpincopallo.it/Notifications/GetByCustomerAndLastID/customersNotificationsInfos?name={0}&name={1}&lastNotificationID={2}&lastNotificationID={3}",
           _testName[0], _testName[1],
           _testNotificationID, _testNotificationIDBis);

    IHttpRouteData routeData = GetRouteData(Url);
    routeData.Values["name"].Should().Be(_testName);
}

在传递数组时还有其他方法进行单元测试吗?

【问题讨论】:

  • 我相信没有办法对它进行“单元”测试,相反,您可以为您的方法/.它看起来就像使用带有查询参数/ POST Payload 的 http 客户端调用您的方法,并将来自服务器的结果与您期望的结果进行比较。

标签: c# asp.net unit-testing asp.net-web-api


【解决方案1】:

也许您可以使用List&lt;string&gt; 而不是string[],如this answer?

此外,您可能需要在查询字符串中输入 name[] 而不是 name。

编辑
在研究了这个之后,我想知道在GetRouteData 调用期间是否没有完成非简单类型的模型绑定——毕竟,路由不考虑这些类型,你不能创建两个不同的路由,例如。传递的数组中的元素数。

因此,您应该研究模型绑定而不是请求路由。 要在不实际执行调用的情况下测试您的代码,您可以手动检索 ModelBinder 对象并使用它来解析 URL。 This test from the ASP.NET source code might be relevant for you.

【讨论】:

  • 根据stackoverflow.com/questions/9508265/… .NET 期望数组要么不带括号,要么带索引括号——?name=first&amp;name=last 或 name[0]=first&amp;name[1]=last 对应于 Action 参数 string[] name,但我之前对此感到困惑.顺便提一下,我认为 PHP 更喜欢 ?name[]=first&amp;name[]=last.
  • @Martin 我重构了我的代码以使用您的解决方案对其进行测试,但它不起作用。问题是一样的:routeData.Values 不包含参数的任何信息。
  • 您是否尝试过设置断点,然后从浏览器执行请求?这可能是由于GetRouteData 中的问题。
  • @MartinWiboe 我已经从“功能”级别对其进行了测试。有用。我想做的是用单元测试来测试它
  • @FrancescoB。我知道了。我用不同的方法更新了我的答案。如果您尝试一下,我想知道它是否适合您。
【解决方案2】:

我认为您应该创建一个新方法,该方法将自动确定数组元素的数量并将它们公开给 url。

private static void ParameterSubstitution(string[] testName, string[] testNotification, ref string url)
{
    const string firstParametrName = "name";
    const string secondParametrName = "lastNotificationID";
    // first parametr
    url += string.Format("?{0}={1}", firstParametrName, string.Join(string.Format("&{0}=", firstParametrName), testName));
    // second parametr
    url += string.Format("&{0}={1}", secondParametrName, string.Join(string.Format("&{0}=",secondParametrName), testNotification));
}

然后你可以像这样使用它:

var testName = new[] { "Name1", "Name2"};
var testNotification = new[] { "Notification1", "Notification2", "Notification3" };

var Url =
    @"http://www.testpincopallo.it/Notifications/GetByCustomerAndLastID/customersNotificationsInfos";

ParameterSubstitution(testName, testNotification, ref Url);

【讨论】:

    【解决方案3】:

    您可以为数组项创建查询字符串参数列表,然后使用 String.Join 方法将它们连接起来,并以 & 作为分隔符。这应该很容易为您提供所需的查询字符串。

    [TestMethod]
            public void GetNotificationsByCustomerAndId_ArrayOverload_Should_Match_InputParameter_name()
            {
                string[] _testName = new string[] { _testCustomer, _testCustomerBis };
    
                // ASSUMING _testNotificationIDBis IS STRING ARRAY
                List<string> nParams = _testName.Select(n => string.Format("lastNotificationID={0}", n)).ToList<string>();
                string Url = string.Format(
                   "http://www.testpincopallo.it/Notifications/GetByCustomerAndLastID/customersNotificationsInfos?name={0}&name={1}&{2}",
                   _testName[0], _testName[1],
                   String.Join("&", nParams.ToArray()));
    
                IHttpRouteData routeData = GetRouteData(Url);
                routeData.Values["name"].Should().Be(_testName);
            }
    

    【讨论】:

      猜你喜欢
      • 2016-05-15
      • 2016-03-25
      • 1970-01-01
      • 2017-05-01
      • 2022-01-14
      • 2015-07-24
      • 2012-06-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多