2015-10-22 160 views
2

版本温莎城堡部分嘲讽3.3.0.0起订量4.2.1507.118与起订量和温莎城堡

看来,起订量自带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属性:(原文如此)

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

DefaultValue的默认值是DefaultValue.Empty,所以这就是你需要明确地将其设置为DefaultValue.Mock的原因。

当你这样做时,mock将返回来自方法的其他代理值而没有显式的设置。如果返回值是一个具体类型,Moq将尝试创建该类型的值,但只有当该类型具有无参数构造函数时才会这样做。如果不存在无参数构造函数,则在尝试调用该方法时会引发异常。


你可能想看看把温莎城堡变成Auto-Mocking Container


根据以下评论,我无法重现该问题。假设AuthorizeDatavirtual(它不高于,但其评价权利要求),本测试通过:

[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

马克,我的意思是当调用Container.Resolve ().AnotherMethod();这个方法返回一个Person类型对象列表。这个方法没有设置,所以我对CallBase的理解是它应该调用底层类,但是我的底层类永远不会被调用。我有一个永远不会被击中的断点。我怀疑这个问题可能与模拟在Castle Windsor注册的方式有关? –