C# 单元测试Asp.NETWebAPI:如何使用[FromUri]参数测试方法的正确路由
我想测试这个控制器:C# 单元测试Asp.NETWebAPI:如何使用[FromUri]参数测试方法的正确路由,c#,asp.net,unit-testing,asp.net-web-api,C#,Asp.net,Unit Testing,Asp.net Web Api,我想测试这个控制器: [HttpGet] public IList<Notification> GetNotificationsByCustomerAndId([FromUri] string[] name, [FromUri] int[] lastNotificationID) { return _storage.GetNotifications(name, lastNotificationID, _topX); } 当您传递数组时,还有其他方法进行单元
[HttpGet]
public IList<Notification> GetNotificationsByCustomerAndId([FromUri] string[] name, [FromUri] int[] lastNotificationID)
{
return _storage.GetNotifications(name, lastNotificationID, _topX);
}
当您传递数组时,还有其他方法进行单元测试吗?也许您可以使用列表而不是字符串[],如中所示
此外,您可能需要在查询字符串中输入名称[],而不是名称
编辑
在深入研究这个问题之后,我想知道在GeTruttDebug调用期间是否没有完成非简单类型的模型绑定——毕竟,路由不考虑这些类型,并且不能创建两个不同的路由,例如通过数组中的元素数量。
因此,您应该研究模型绑定,而不是请求路由。
要在不实际执行调用的情况下测试代码,可以手动检索ModelBinder对象并使用该对象解析URL 我认为您应该创建一个新方法,该方法将自动确定数组元素的数量并将它们公开给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);
您可以为数组项创建查询字符串参数列表,然后使用string.join方法和分隔符(&as)将它们连接起来。这将很容易获得所需的查询字符串
[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);
}
我相信没有单元测试的方法,相反,您可以为您的方法/对内存中的HttpServer进行集成测试。这看起来像是使用带有查询参数/POST有效负载的http客户端调用您的方法,并将来自服务器的结果与您期望的结果进行比较。根据.NET的要求,数组需要不带括号或带索引括号-?name=first&name=last或name[0]=first&name[1]=last对应于操作参数字符串[]name,但我以前对此感到困惑。我想PHP更喜欢?name[]=first&name[]=last。@Martin我重构了代码,用您的解决方案对其进行了测试,但它不起作用。问题是相同的:routeData。值不包含任何参数信息。是否尝试设置断点,然后从浏览器执行请求?这可能是因为GetRouteData中存在问题。@MartinWiboe我已经从功能级别对其进行了测试。它起作用了。我想做的是用一个单元来测试它test@FrancescoB. 我懂了。我用不同的方法更新了我的答案。如果你尝试一下,我想听听它是否适合你。
[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);
}