Обновить
0
0
Евгений Ващенко@VasEug

Software Developer (C#, SQL)

Отправить сообщение

Здесь я опять допустил ошибку :). Вызов должен быть такой:

var actual = Reflector.CallMethod(typeof(Processor<>), "Method", MemberAccessibility.Public, null, null, inputs, null, expected.GetType());

Если мы допускаем null-объекты в типе R, то необходимо ожидаемый тип передавать так же в параметрах, иначе можно в ограничении аргументов метода для типа R поставить notnull. А так все должно работать, проверил.

Опечатка в коде вызова метода:

var actual = Reflector.CallMethod(typeof(Processor<>), "Method", MemberAccessibility.Public, null, null, inputs, null, null);

Появилось немного времени и дабы исключить последующие комментарии вышенаписанной тематики, дам более развернутое объяснение для чего это было сделано в тестировании. Скажу сразу, что я ни в коей мере не намерен оспаривать то что написал автор вышенаписанных комментариев, но это действительно касается именно типизированных данных. Здесь приведу пример, который должен удовлетворить подобных комментаторов.

Например, есть у нас такой код:

public class Subject<T1, T2>
{
}

public class Processor<T1>
{
  public static R Method<M1, M2, R>(M1 m1, M2 m2)
    where M1 : Subject<T1, M2>
  {
  }
}

public class B1 { }
public class B2 { }
public class C1 { }
public class C2 { }

И на вход тестовой функции поступают из внешенго источника "нетипизированные" приведенные к типу object экземпляры классов Subject<B1, C2>, Subject<B2, C1>, Subject<B2,C2>..., вернее массив параметров тестируемого метода Method класса Processor. Таким источником может быть как файл, база данных и в моем случае это также отлаживаемый генератор объектов, который может генерировать данные универсальных типов в runtime. Если использовать предлагаемую надстройку, то необходимо написать лишь один вызов.

[Xunit.Theory]
[MemberData(nameof(TestData))]
public void TestTheory(object[] inputs, object expected)
{
  var actual = Reflector.CallMethod(typeof(Processor<>), MemberAccessibility.Public, null, null, inputs, null, null);
  Assert.Equal(expected, actual);
}

Так давайте уже придем к взаимопониманию...

Никто здесь не спорит что типизация это плохо и т.п. Тем более я и сам в своем случае начинал писать методы пытаясь типизировать объекты, но потом меня это занятие сильно утомило, т.к. писать тесты на несколько сотен универсальных функций да еще и с различными наборами параметров на каждую. Притом данные приходят из внешнего источника, да еще и в некоторых случаях могут ожидаться объекты любых типов и они гораздо сложнее чем те которые приводите вы. И вот вы сами же показали выше написанные адаптеры. А чем объемнее и сложнее код, тем выше вероятность сделать ошибку в тестах и отлаживать уже их. И загружались у меня из внешннего источника куда более сложные типы данных чем int и long, И сколько это бы заняло времени? Вот и был найден способ ускорить данную процедуру. Тем более что написав с десяток адаптеров, пришлось отлаживать уже их. Поэтому и было принято данное решение. Вам не требуется тратить время на написание различных типизирующих адаптеров. Здесь вам нужно лишь передать десериализованный объект сразу в функцию без каких-либо накладных расходов.

Еще раз скажу, что фактически здесь приводится инструмент позволяющий очень сильно упростить работу с унивирсальными типами и методами и "нетипизированными" данными которые надо обработать этими методами. И писалась данная надстройка конкретно не для использования в тестировании, но использование в конкретном кейсе тестирования приводится в качестве ПРИМЕРА. Здесь статья не про методологию тестирования, а про применение надстройки работы с отражением в конкретном примере тестирования. Вы видимо не так поняли посыл статьи, или я неправильно его раскрыл.

P.S. Да, вспомнил еще в чем была трудность. Типы объектов которые приходили на тестирование также являлись закрытыми универсальными типами с несколькми параметрами.

Если у вас данные приходят десериализованные из внешнего источника а тестируемые методы и типы являются универсальными, то ваш код уже не подходит, и вам также придется использовать рефлексию. Идея именно в этом заключалась. Смысл этой надстройки как раз в том чтобы упростить работу с универсальными типами и методами когда на входе "нетипизированые" данные.

По поводу тестирования закрытых членов я полностью с вами согласен, но...приходилось писать специальный тест на стороннюю сборку. Да и использование этой надстройки гораздо шире, чем тесты.

Э-э-э-х... Прочитал статью, вспомнил что МК-61 храню. Достал, поностальгировал... мне купили его в 1987 году. Вместе с ним еще и МК-51 нашел.Для своего времени MK-61 очень неплох был. Хотя уже набирала обороты эра "Специалист"-ов и "Spectrum"-ов.

Информация

В рейтинге
Не участвует
Откуда
Санкт-Петербург, Санкт-Петербург и область, Россия
Дата рождения
Зарегистрирован
Активность

Специализация

Десктоп разработчик, Бэкенд разработчик
Старший
C#
Алгоритмы и структуры данных
Entity framework
WPF
Windows Forms
Разработка программного обеспечения
Многопоточность
Проектирование баз данных
T-SQL
Linq