Получить случайные данные, используя Generics - PullRequest
2 голосов
/ 07 октября 2008

Один из наших модульных тестов - заполнение свойств внутри наших бизнес-объектов случайными данными.

Эти свойства имеют различные внутренние типы, и поэтому мы хотели бы использовать мощь обобщений для возврата данных типа, который вы передаете. Что-то вроде:

public static T GetData<T>()

Как бы вы подошли к этому? Будет ли работать интерфейс низкого уровня? (IConvertible)

Ответы [ 4 ]

16 голосов
/ 07 октября 2008

Вы можете сохранить «простой в использовании» интерфейс GetData, который у вас есть, но внутри есть Dictionary , где каждое значение является Func для соответствующего типа. GetData будет иметь такую ​​реализацию, как:

public static T GetData<T>()
{
    object factory;
    if (!factories.TryGet(typeof(T), out factory))
    {
         throw new ArgumentException("No factory for type " + typeof(T).Name);
    }
    Func<T> factoryFunc = (Func<T>) factory;
    return factoryFunc();
}

Затем вы настроили бы фабричный словарь в статическом инициализаторе с одним делегатом для каждого типа случайных данных, которые вы хотите создать. В некоторых случаях вы можете использовать простое лямбда-выражение (например, для целых чисел), а в некоторых случаях делегат может указывать на метод, выполняющий больше работы (например, для строк).

Кстати, вы можете использовать мой StaticRandom класс для многопоточного RNG.

2 голосов
/ 07 октября 2008

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

Итак, я полагаю, что вы действительно пишете дымовые тесты, чтобы увидеть, как ваше программное обеспечение работает с большими наборами данных. Здесь я думаю, что вы должны реализовать определенный генератор для каждого из ваших типов бизнес-объектов, как кто-то другой уже предложил - чтобы убедиться, что данные разумно похожи на то, что вы ожидаете в производстве (например, если идентификаторы являются последовательными, то генерируйте их последовательно не случайно).

1 голос
/ 07 октября 2008

Это зависит от того, какие данные вы хотите рандомизировать, потому что way или алгоритма , который вы хотите использовать, полностью отличается в зависимости от типа.

Например:

// Random int
Random r = new Random();
return r.Next();

// Random Guid
return Guid.NewGuid();

...

Так что это, очевидно, делает использование дженериков хорошей иллюстрацией на стороне пользователя, но не добавляет никакой ценности тому, как вы пишете класс. Вы можете использовать предложение switch или словарь (как предлагает Джон Скит):

switch(typeof(T))
{
    case System.Int32:
        Random r = new Random();
        return (T)r.Next();
    case System.Guid:
        return (T)Guid.NewGuid();
    ...

Тогда вы будете использовать класс так, как ожидаете:

RandomGenerator.GetData<Guid>();
...
0 голосов
/ 11 мая 2011

Я бы использовал AutoPoco для генерации необходимых данных для тестирования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...