2015-10-22 2 views
2

версии Замок Виндзор 3.3.0.0 Moq 4.2.1507.118частичное насмешливый с Moq и замок Виндзор

оказывается, что Moq поставляется с CallBase настройки, которые при включении делегаты вызовы в любой не-установки методы до базового объекта.

var mock = new Mock<MyService> {CallBase = true}; 

, к сожалению, как только я зарегистрировать его в замок Виндзор, все не издевались методы немедленно возвращает нуль, не лежащие в основе логики больше не вызывается.

  Container.Register(Component 
      .For<MyService>() 
      .Instance(mock.Object) 
      .LifeStyle.Singleton 
      ); 

Я также попробовал несколько разных стилей жизни.

так, когда я делаю это:

mock.setup(x => x.SomeMethod).Returns(myMockedData); 

это работает, как ожидалось:

Container.Resolve<MyService>().SomeMethod(); 

но теперь это возвращает нуль:

Container.Resolve<MyService>().AnotherMethod(); 

как только я удалить издеваться Регистрация, AnotherMethod начинает работать по-прежнему.

конкретнее пример кода

public class Auth : IAuth 
{ 
    // mocked succesfully 
    public IEnumerable<T> AuthorizeData<T>(IEnumerable<T> data) { ... } 

    // never gets called 
    public virtual List<User> GetAllUsers() { 
     return new List<User>{new User{FIRST_NAME = "test"}}; 
    } 
} 

фиктивный метод

protected static Mock<T> GetMock<T>() where T : class { 

     var mock = new Mock<T> {CallBase = true, DefaultValue = DefaultValue.Mock}; 
     IoC.Container.Register(Component 
      .For<T>() 
      .Instance(mock.Object) 
      .LifeStyle.Transient 
      ); 
     return mock; 
    } 

макет установки

GetMock<IAuth>().Setup(x => x.AuthorizeData(It.IsAny<IEnumerable<DO>>())) 
       .Returns((IEnumerable<DO> data) => data); // pass through input data (do not authorize 

подытожить снова, AuthorizeData издевались успешно, GetAllUsers() возвращает пустой список. и первоначальный класс никогда не называется

ответ

1

CallBase не контролирует, как генерируются возвращаемые значения. Для этого вам необходимо установить DefaultValue свойство: (. SiC)

var mock = new Mock<MyService> { CallBase = true, DefaultValue = DefaultValue.Mock }; 

Значение по умолчанию для DefaultValue является DefaultValue.Empty, так что по этой причине вам нужно явно установить его DefaultValue.Mock.

Когда вы это сделаете, mock вернет другие значения прокси-сервера из методов без явных настроек. Если возвращаемое значение является конкретным типом, Moq попытается создать значение этого типа, но оно будет делать это только в том случае, если этот тип имеет конструктор без параметров. Если конструктор без параметров не существует, он будет вызывать исключение при попытке вызвать метод.


Вы можете посмотреть в поворот замок Виндзор в Auto-Mocking Container.


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

[Fact] 
public void Repro() 
{ 
    var td = new Mock<Auth> 
    { 
     CallBase = true, 
     DefaultValue = DefaultValue.Mock 
    }; 
    var container = new WindsorContainer(); 
    container.Register(Component.For<Auth>().Instance(td.Object)); 

    td 
     .Setup(a => a.AuthorizeData<string>(new string[0])) 
     .Returns(new[] { "foo", "bar" }); 

    Assert.Equal(
     new[] { "foo", "bar" }, 
     container.Resolve<Auth>().AuthorizeData(new string[0])); 
    Assert.NotEmpty(container.Resolve<Auth>().GetAllUsers()); 
} 
+0

привет, спасибо за письма. единственное изменение поведения, которое я вижу до сих пор с этим набором свойств, заключается в том, что мой метод возвращает пустой список вместо null. моя точка останова внутри фактического сервиса не попала, что привело меня к тому, что он все еще не пропустил вызов через –

+0

@SonicSoul Какой список? Какой тип? –

+0

Mark, я имею в виду при вызове Container.Resolve () .AnotherMethod(); этот метод возвращает объект типа List of Person. Для этого метода нет настройки, поэтому мое понимание CallBase заключается в том, что он должен вызывать базовый класс, но мой базовый класс никогда не вызван. У меня есть точка останова, которая никогда не попадает. Я подозреваю, что проблема может быть связана с тем, как макет регистрируется в Castle Windsor? –

Смежные вопросы