AutoFixture не знает об ограничениях домена для параметра string
для вашего класса. Это должно дать подсказку, что, возможно, этот тип не самый подходящий параметр для класса. Это классический c пример Primitive Obsession .
. Вместо этого вы можете улучшить свой сервис, вместо этого напрямую принять тип, который воплощает идею, что это CronExpression:
protected ServiceBase(CronExpression cronExpression, TimeZoneInfo timeZoneInfo)
{
_cronExpression = cronExpression;
...
}
Таким образом, гарантируется, что BaseService
будет передан действительный CronExpression
. Если это не так, то создание CronExpression
уже будет неудачным.
Вы можете подумать, что мы просто переместили проблему: как вы теперь скажете AutoFixture создать действительный CronExpression
?
Преимущество переноса работы на построение CronExpression
заключается в том, что любая настройка, созданная для создания действительного CronExpression
, теперь может использоваться повторно для любого другого типа, который потребует этого. Это уменьшит церемонию для любых будущих тестов, которые в конечном итоге будут нуждаться в этом типе. Не говоря уже о всех других преимуществах избегания примитивной одержимости.
Что касается сообщения AutoFixture о том, как создать действительный CronExpression
, существует множество вариантов. Вы можете напрямую ввести один действительный:
fixture.Inject(CronExpression.Parse("myValidCronExpression"));
Если вы хотите иметь возможность выбрать несколько, вы можете использовать ElementsBuilder
для выбора из пула допустимых значений:
public void Test()
{
var fixture = new Fixture();
fixture.Customizations.Add(new ElementsBuilder<CronExpression>(
new[] { "validExpr1", "validExpr2" }
.Select(s => CronExpression.Parse(s))
.ToArray()))
...
}
Наибольший контроль над созданием для этого типа можно получить, создав реализацию ISpecimenBuilder
, которую я опущу в этом ответе. Если вы хотите go по этому маршруту, есть много примеров и здесь, и в других местах.
После того, как одна из этих настроек будет выполнена для AutoFixture, создание вашего sut будет работать:
var sut = fixture.Create<TestService>();
Примечание: я не проверял, можно ли напрямую создать экземпляр TimeZoneInfo
создателями образцов AutoFixture по умолчанию. Если это невозможно, аналогичный метод можно использовать и для этого типа.