2015-10-22 89 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註冊的方式有關? –