Search code examples
unit-testingservicestackmoqservicestack.redis

How to unit test Service Stacks Redis Client with Moq


I'm trying to understand how can I mock the IRedisClientsManager so that I can unit test the Handle Method below using Moq.

Cheers

 public class PropertyCommandHandler : ICommandHandlerFor<PropertySaveRequest, PropertyCommandResult>
{
    private readonly IRedisClientsManager _manager;

    public PropertyCommandHandler(IRedisClientsManager manager)
    {
        this._manager = manager;
    }

    public PropertyCommandResult Handle(PropertySaveRequest request)
    {
        request.Property.OwnerId.ValidateArgumentRange();

        using (var client =_manager.GetClient())
        {
            var propertyClient = client.As<Model.Property>();

            var propertyKey = string.Format("property:{0}", request.Property.OwnerId);

            propertyClient.SetEntry(propertyKey, request.Property);

            client.AddItemToSet("property", request.Property.OwnerId.ToString());
        }

        return new PropertyCommandResult() {Success = true};
    }
}

Which I call from the service like so

public class PropertyService : Service, IPropertyService
{
    private readonly ICommandHandlerFor<PropertySaveRequest, PropertyCommandResult> _commandHandler;

    public PropertyService(ICommandHandlerFor<PropertySaveRequest, PropertyCommandResult> commandHandler)
    {
        this._commandHandler = commandHandler;
    }

    public object Post(PropertySaveRequest request)
    {
        if (request.Property == null)
            throw new HttpError(HttpStatusCode.BadRequest, "Property cannot be null");

        var command = _commandHandler.Handle(request);
        return command;
    }
}

so far this has been the approach - not sure if on right track

    [Test]
    public void TestMethod1()
    {
        //arrange
        _container = new WindsorContainer()
                .Install(new PropertyInstaller());

        var mock = new Mock<IRedisClientsManager>();
        var instance = new Mock<RedisClient>();
        mock.Setup(t => t.GetClient()).Returns(instance);
        // cannot resolve method error on instance
        // stuck ...
        var service = _container.Resolve<IPropertyService>(mock);
    }

Solution

  • In short, since RedisClient implements IRedisClient, did you try to create the mock using the interface?

     var instance = new Mock<IRedisClient>();
    

    why are you using a real container for your unit test? You should use an auto-mocking container or simply (since you are already taking care of the mock manually) create a real instance of your test target supplying mocks as dependencies

    var target= new PropertyCommandHandler(mock);
    

    BTW IMHO a "command handler" that returns a value sounds like a smell...