Предоставлять данные для определенных полей во время выполнения в Bogus

В настоящее время я создаю набор правил для поддельных данных, используя Bogus. Они будут использоваться набором фиктивных сервисов. Под этим я подразумеваю, что создаю макет службы поиска, которая возвращает поддельные данные.

Для большинства служб введенные критерии поиска должны влиять на выходные данные (например, если вы используете службу для поиска организаций, базирующихся в Мексике, поддельные данные должны включать только адреса, находящиеся в Мексике). Если вы ищете организации с именами, начинающимися с «Micro*», я хочу иметь возможность использовать этот ввод, чтобы влиять на то, как создаются данные.

До сих пор мне удавалось это делать путем создания подкласса Faker и предоставления собственного метода Generate, который принимает некоторые входные данные. Затем я могу вызвать метод Faker.Generate(), разрешить ему предоставить некоторые данные, а затем изменить определенные поля, прежде чем передать их обратно.

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

// This shows my current workaround
public static Organization Generate(string searchCode)
{
    var organization = Faker.Generate();
    organization.Code = searchCode;
    return organization;
}

person alexcyoung    schedule 20.05.2019    source источник
comment
Я не знаком с Богусом; это требуется? Если нет, это было бы очень легко сделать с помощью Moq.   -  person Lews Therin    schedule 20.05.2019
comment
Цель Bogus заключается в том, что он генерирует фактические данные, например. имена, адреса, номера телефонов и т.д. Это нормально. Я хочу сделать это неслучайным в некоторых ситуациях   -  person alexcyoung    schedule 20.05.2019


Ответы (1)


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

Итак, как грубый ориентир...

  • Если ваши графы объектов глубокие и сложные, рассмотрите возможность имитации объектов с фасадом Faker. Это означает создание static фабричных методов, таких как:
void Main()
{
   Search("Micro*").Dump();
}

public Organization Search(string search)
{
   return CreateOrganization(code: search);
}

static Organization CreateOrganization(string code = null){
   var faker = new Faker();
   //setup complicated child dependency graphs here.
   //then finally create your parent object below.
   return new Organization{
      Code = code ?? faker.Company.CompanyName()
   };
}

public class Organization
{
   public string Code { get; set; }
}

  • Если вы создаете объекты типа POCO/DTO, которые не имеют очень большого или сложного графа объектов, то использование Faker<T> должно работать очень хорошо. Например:
void Main()
{
   Search("Micro*").Dump();
}

public Organization Search(string code){
   var customOrgFaker = Fakers.OrgFaker.RuleFor(x => x.Code, f => code);
   return customOrgFaker.Generate();
}

static class Fakers{

   public static Faker<Organization> OrgFaker => 
             new Faker<Organization>()
                 .RuleFor(o => o.Code, f => f.Company.CompanyName());

}

Обратите внимание, что в приведенном выше примере Faker<T> я вызываю .RuleFor(_ => _.Code, ...) дважды, но будет применяться только самый последний вызов .RuleFor. В этом случае .RuleFor(x => x.Code, f => code) является последним вызовом перед .Generate(). По сути, это похоже на переопределение настройки по умолчанию .RuleFor(o => o.Code, f => f.Company.CompanyName()) в статическом конструкторе Fakers.

Также обратите внимание, что при каждом доступе к свойству .OrgFaker создается new Faker<T>. Это хорошо, потому что каждый доступ к свойству .OrgFaker создает выделенный экземпляр Faker<T> для вашего потребления и настройки.

Если это не работает для вас, и у вас есть только один экземпляр Faker<T> для работы, вы можете использовать метод Faker<T>.Clone() для клонирования Faker<T> и снова вызвать .RuleFor с расходящимся правилом, не испортив исходный экземпляр Faker<T>.

Прощальный совет...

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

Надеюсь, это поможет!

person Brian Chavez    schedule 21.06.2019
comment
Отлично, спасибо! В итоге я реализовал что-то похожее на это, но проведу рефакторинг на основе вашего совета. - person alexcyoung; 21.06.2019