Ответ 1
Чтобы изменить стратегию для одного типа (MyClass
):
fixture.Customize<MyClass>(c => c.FromFactory(
new MethodInvoker(
new GreedyConstructorQuery())));
Чтобы изменить стратегию по всем направлениям:
fixture.Customizations.Add(
new MethodInvoker(
new GreedyConstructorQuery()));
Однако, как выясняется, использование GreedyConstructorQuery по всем направлениям, скорее всего, проблематично, как демонстрирует следующий фрагмент кода. Представьте себе класс с этим конструктором:
public Foo(string name)
{
this.name = name;
}
Этот тест выдает исключение:
[Test]
public void GreedyConstructor()
{
Fixture fixture = new Fixture();
fixture.Customizations.Add(new MethodInvoker(new GreedyConstructorQuery()));
Foo foo = fixture.CreateAnonymous<Foo>();
}
Исключение составляет:
Ploeh.AutoFixture.ObjectCreationException: AutoFixture не смог создать экземпляр из System.SByte *, скорее всего, потому что он не имеет открытого конструктора, является абстрактным или непубличным.
Итак, что это о SByte *? Там нет SByte * в Foo...
Ну, да, есть. Помещая MethodInvoker в настройке, он переопределяет все стратегии создания по умолчанию, включая строку для строк. Вместо этого он ищет самый жадный конструктор для строки, а именно:
public String(sbyte* value, int startIndex, int length, Encoding enc);
И там sbyte *...
По-прежнему можно заменить алгоритм выбора скромного конструктора алгоритмом жадного алгоритма, он чуть более вовлечен, чем я впервые понял.
Что вы можете сделать, так это:
Напишите небольшой класс, подобный этому:
public class GreedyEngineParts : DefaultEngineParts
{
public override IEnumerator<ISpecimenBuilder> GetEnumerator()
{
var iter = base.GetEnumerator();
while (iter.MoveNext())
{
if (iter.Current is MethodInvoker)
yield return new MethodInvoker(
new CompositeMethodQuery(
new GreedyConstructorQuery(),
new FactoryMethodQuery()));
else
yield return iter.Current;
}
}
}
и создайте экземпляр Fixture следующим образом:
Fixture fixture = new Fixture(new GreedyEngineParts());
Это должно работать.