Параметр конструктора IList <something>и автофикс - PullRequest
3 голосов
/ 09 сентября 2010

Используя autofixture , я пытаюсь создать анонимный экземпляр Project:

 _f=new Fixture().Customize(new AutoMoqCustomization());
 _p=_f.CreateAnonymous<Project>();

Это не удалось, потому что Project публичный конструктор требует IList<Partner>

public Project(/*.....*/,IList<Partner> partners){
  Guard.AgainstEmpty(partners);
}

Трассировка стека не имеет смысла (по крайней мере - для меня).Просто какое-то отражение yada-yada:

fail: System.Reflection.TargetInvocationException: Исключение было сгенерировано целью вызова.
---- System.ArgumentException: значение не падаетв ожидаемый диапазонпартнеры, чтобы построить его?


Это не вина IList<Partners>.Есть еще один параметр с именем Priority.Priority сам содержит Measure, Measure содержит IList<Indicator> и вызывает Guard.AgainstEmpty(indicators) в конструкторе.

Так это выглядит примерно так:

fixture.CreateAnonymous<Foo>(); //kaboom!
public class Foo{
  public Foo(IList<Bar> bars){
    Guard.AgainstEmpty(bars); //just checks count for ienumerable & throws if 0
    Bars=bars;
  }
  public IList<Bar> Bars {get;private set;} //should be readonly collection...
}

public class Fizz{
  public Fizz(Foo foo){
    Foo=foo;
  }
  public Foo{get;private set;}
}

public class Bar{}

Конструкция не удалась в Guard.AgainstEmpty метод.Итак, возникает вопрос - как убедиться, что AutoFixture заполняет некоторые столбцы в коллекции баров, прежде чем создавать foos?

1 Ответ

1 голос
/ 09 сентября 2010

Это помогает.Часто помогает просмотр источника .

var indicators=_f.CreateMany<Indicator>();
_f.Register<IList<Indicator>>(()=>indicators.ToList());

Возможно, есть и лучший способ.


В целом, на данный момент это выглядит так:

  _f=new Fixture().Customize(new AutoMoqCustomization());
  var indicators=_f.CreateMany<Indicator>();
  _f.Register<IList<Indicator>>(()=>indicators.ToList());
  var regionName=_f.CreateAnonymous<string>();
  _f.Register<string,Country,bool,Region>((name,country,call)=>
    new Region(regionName,_f.CreateAnonymous<Country>(),true));
  _c.Set(x=>x.Regions,_f.CreateMany<Region>().ToList());
  _f.Register<IList<ManagementBoardEntry>>(()=>
    _f.CreateMany<ManagementBoardEntry>().ToList());
  _f.Register<IList<FinancialInfoEntry>>(()=>
    _f.CreateMany<FinancialInfoEntry>().ToList());
  _f.Register<IList<Partner>>(()=>_f.CreateMany<Partner>().ToList());
  _p=_f.CreateAnonymous<Project>();

Невозможно назвать это красивым (приветствуются любые предложения по рефакторингу), но это все же намного лучше, чем писать все вручную.


Использование IList неправильный выбор дляконечно.Еще хуже - я использую IList для свойств тоже.Это предлагает клиенту использовать их напрямую, а не проходить через объединенный корень.

Есть один недостаток при использовании params.Не могу использовать более одного (если я не пропускаю некоторые основы снова).И я получаю список в качестве входных данных (часть DOM Excel лист), Не могу знать время компиляции, сколько элементов будет там.

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

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

В любом случае - спасибо за отличные советы.Я буду продолжать узнавать больше об AutoFixture.

...