Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Moq to mock up the StackExchange.Redis ConnectionMultiplexer class?

I am working to mock up behaviors related to the StackExchange.Redis library, but can't figure out how to properly mock the sealed classes it uses. A specific example is in my calling code I'm doing something like this:

    var cachable = command as IRedisCacheable;

    if (_cache.Multiplexer.IsConnected == false)
    {
        _logger.Debug("Not using the cache because the connection is not available");

        cacheAvailable = false;
    }
    else if (cachable == null)
    {

The key line in there is _cache.Multiplexer.IsConnected where I'm checking to make sure I have a valid connection before using the cache. So in my tests I want to mock up this behavior with something like this:

    _mockCache = new Mock<IDatabase>();
    _mockCache.Setup(cache => cache.Multiplexer.IsConnected).Returns(false);

However, while that code compiles just fine, I get this error when running the test:

Moq exception thrown within the test

I have also tried mocking the multiplexer class itself, and providing that to my mocked cache, but I run into the fact the multiplexer class is sealed:

    _mockCache = new Mock<IDatabase>();
    var mockMultiplexer = new Mock<ConnectionMultiplexer>();
    mockMultiplexer.Setup(c => c.IsConnected).Returns(false);
    _mockCache.Setup(cache => cache.Multiplexer).Returns(mockMultiplexer.Object);

...but that results in this error:

The error thrown when trying to mock a sealed class

Ultimately I want to control whether that property is true or false in my tests, so is there a correct way to mock up something like this?

like image 827
Sam Storie Avatar asked Feb 04 '15 16:02

Sam Storie


1 Answers

The best approach in my opinion is to wrap all of your Redis interaction in your own class and interface. Something like CacheHandler : ICacheHandler and ICacheHandler. All of your code would only ever speak to ICacheHandler.

This way, you eliminate a hard dependency on Redis (you can swap out the implementation of ICacheHandler as you please). You can also mock all interaction with your caching layer because it's programmed against the interface.

You should not test StackExchange.Redis directly - it is not code you've written.

like image 160
Haney Avatar answered Oct 11 '22 18:10

Haney