2014-11-13 2 views
0

Моим вопроса вытекает из этого вопроса: Is this possible with Unity (Instead of Castle Windsor)?Единство и авто-насмешливые с NSubstitute (или что-то еще)

Вот класс от ответа:

protected override void Initialize() 
{ 
    var strategy = new AutoMockingBuilderStrategy(Container); 

    Context.Strategies.Add(strategy, UnityBuildStage.PreCreation); 
} 

class AutoMockingBuilderStrategy : BuilderStrategy 
{ 
    private readonly IUnityContainer container; 
    private readonly Dictionary<Type, object> substitutes 
     = new Dictionary<Type, object>(); 

    public AutoMockingBuilderStrategy(IUnityContainer container) 
    { 
     this.container = container; 
    } 

    public override void PreBuildUp(IBuilderContext context) 
    { 
     var key = context.OriginalBuildKey; 

     if (key.Type.IsInterface && !container.IsRegistered(key.Type)) 
     { 
      context.Existing = GetOrCreateSubstitute(key.Type); 
      context.BuildComplete = true; 
     } 
    } 

    private object GetOrCreateSubstitute(Type type) 
    { 
     if (substitutes.ContainsKey(type)) 
      return substitutes[type]; 

     var substitute = Substitute.For(new[] {type}, null); 

     substitutes.Add(type, substitute); 

     return substitute; 
    } 
} 

Опубликованное решение там хорошо работает для Единый объект. Если вы видите решение, некоторое время он будет возвращать же объект каждый раз я называю Resolve

Это хорошо в тесте, как следующее:

var myObjectWithInnerMockedObjects = UnityContainer.Resolve<ISomeInterface>(); 
var internalAutoMockedObject = UnityContainer.Resolve<IInnerInterface>(); 

Решение размещен в указанном вопросе хорошо работает для выше.

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

Так эффективно цепь может быть:

- ActualObject 
    - InnerActualObjectDependency 
     - MockedDependency (since this was not mapped in Unity, a mock was created) 

Проблема заключается в том, если я создаю 2 таких объектов, как издевается указывают на же объекта.

Если я удалю проверку CONTAINS, в методе GetOrCreateSubstitute(), то я получаю новый макет каждый раз ... Но тогда как мне получить доступ к макету конкретного объекта, чтобы установить на него ожидания? :-(

Я надеюсь, что я ясно с вопросом !!

ответ

1

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

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

var obj1 = Resolve<IMyInterface>(); 
var obj2 = Resolve<IMyInterface>(); 
var innerDependency = Resolve<IInnerType>(); // Returns the same object that is shared by above 2 objs 

innerDependency.SetExpection(Some expectation); 
obj1.PerformAction(); 
innerDependency.Assert(); 

innerDependency.SetExpection(Some *different* expectation); 
obj2.PerformAction(); 
innerDependency.Assert(); 

Так что самый предлог вопроса неисправен. У нас нет такой гибкости, потому что мы не хотим!