2012-11-01 62 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