Подтвердить что ты не робот

Тестирование модулей Asp.Net WebApi: как проверить правильную маршрутизацию метода с параметрами [FromUri]

Я бы хотел протестировать этот контроллер:

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

Есть ли другой способ unit test, когда вы передаете массивы?

4b9b3361

Ответ 1

Возможно, вы можете использовать List<string>, а не string[], как в этом ответе?

Кроме того, вам может потребоваться поместить name[] вместо name в строку запроса.

Edit
Изучив это, я задаюсь вопросом, не выполняется ли привязка модели к непростым типам во время вызова GetRouteData - в конце концов, маршрутизация не учитывает эти типы, и вы не можете создать два маршрута, которые отличаются, например. количество элементов в переданном массиве.

Итак, вы должны изучить привязку модели вместо маршрутизации запроса. Чтобы протестировать ваш код без фактического выполнения вызова, вы можете вручную загрузить объект ModelBinder и использовать его для анализа URL. Этот тест из исходного кода ASP.NET может иметь для вас значение.

Ответ 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);
        }