2012-11-01 85 views
4

我在一個接口下面的方法簽名:NSubstitute模擬泛型方法

public interface ISettingsUtil 
{ 
    T GetConfig<T>(string setting, dynamic settings); 
} 

我已經嘗試模擬:

var settingsUtil = Substitute.For<ISettingsUtil>(); 
var maxImageSize = settingsUtil.GetConfig<long>("maxImageSize", 
               Arg.Any<dynamic>()).Returns(100L); 

這將引發Microsoft.CSharp.RuntimeBinder.RuntimeBinderException異常二號線:

'long'不包含'Returns'的定義

關於如何正確模擬T GetConfig<T>(string setting, dynamic settings)的任何想法?

回答

3

NSubstitute不適用於使用dynamic的成員。 (Github issue

+0

太糟糕了,NSubstitute迅速成爲我最喜歡的 - 希望問題儘快解決! – Anders

5

對於任何人還在爲此掙扎,你可以在NSubsitute實際模擬動態,它只是需要通過一些小的籃球跳躍。 請參閱下面的模擬對signalR客戶端集線器的調用的情況。

重要的線是這個:

SubstituteExtensions.Returns(_hubContext.Clients.All, _mockClient); 

爲了嘲笑我已經創建了我要聽的方法的接口的動態。然後您需要使用SubstituteExtensions.Returns而不是簡單地鏈接一個.Returns在對象的末尾。
如果你不需要驗證任何東西,你也可以使用匿名對象。

完整的代碼示例如下:

[TestFixture] 
public class FooHubFixture 
{ 
    private IConnectionManager _connectionManager; 
    private IHubContext _hubContext; 
    private IMockClient _mockClient; 

    [SetUp] 
    public void SetUp() 
    { 
     _hubContext = Substitute.For<IHubContext>(); 
     _connectionManager = Substitute.For<IConnectionManager>(); 

     _connectionManager.GetHubContext<FooHub>().Returns(_hubContext); 
     _mockClient = Substitute.For<IMockClient>(); 
     SubstituteExtensions.Returns(_hubContext.Clients.All, _mockClient); 
    } 

    [Test] 
    public void PushFooUpdateToHub_CallsUpdateFooOnHubClients() 
    { 
     var fooDto = new FooDto(); 
     var hub = new FooHub(_connectionManager); 
     hub.PushFooUpdateToHub(fooDto); 
     _mockClient.Received().updateFoo(fooDto); 
    } 

    public interface IMockClient 
    { 
     void updateFoo(object val); 
    } 
} 



public class FooHub : Hub 
    { 
     private readonly IConnectionManager _connectionManager; 

     public FooHub(IConnectionManager connectionManager) 
     { 
      _connectionManager = connectionManager; 
     } 

     public void PushFooUpdateToHub(FooDto fooDto) 
     { 
      var context = _connectionManager.GetHubContext<FooHub>(); 
      context.Clients.All.updateFoo(fooDto); 
     } 
    } 
+1

謝謝佈雷特,這是我確切的問題,我想我愛你! :) – zvolkov

+0

任何想法如何使用靜態'Returns'方法來存根返回動態類型而不是屬性的方法? –

+0

這似乎不工作了。當我使用: 'SubstituteExtensions.Returns(_hubContext.Clients.All,_mockClient);' 在運行時我得到一個錯誤,說它不能分辨我是否調用了需要ObjectProxy或任務的版本作爲第一個論點。 – jfren484