Question

I have the following method signature in an interface:

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

Which I have attempted to mock:

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

This throws a Microsoft.CSharp.RuntimeBinder.RuntimeBinderException exception on the 2nd line:

'long' does not contain a definition for 'Returns'

Any thoughts on how to mock T GetConfig<T>(string setting, dynamic settings) correctly?

Was it helpful?

Solution

NSubstitute does not work with members that use dynamic. (Github issue)

OTHER TIPS

For anyone still struggling with this, you can actually mock dynamics in NSubsitute, it just requires jumping through some minor hoops. See the below case of mocking out calls to a signalR client hub.

The important line is this one:

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

In order to mock the dynamic I have created an interface with the methods I want to listen for. You then need to use SubstituteExtensions.Returns rather than simply chaining a .Returns at the end of the object.
If you don't need to verify anything you could also use an anonymous object.

Full code sample follows:

[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);
        }
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top