c# - 如何使用 Moq 模拟 StackExchange.Redis ConnectionMultiplexer 类?

标签 c# .net unit-testing moq stackexchange.redis

我正在努力模拟与 StackExchange.Redis 库相关的行为,但无法弄清楚如何正确模拟它使用的密封类。一个具体的例子是在我的调用代码中我正在做这样的事情:

    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)
    {

其中的关键行是 _cache.Multiplexer.IsConnected,我在其中检查以确保在使用缓存之前有有效的连接。所以在我的测试中,我想用这样的东西来模拟这种行为:

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

但是,虽然该代码编译得很好,但在运行测试时出现此错误:

Moq exception thrown within the test

我也尝试模拟多路复用器类本身,并将其提供给我的模拟缓存,但我遇到了多路复用器类是密封的事实:

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

...但这会导致此错误:

The error thrown when trying to mock a sealed class

最终我想在我的测试中控制该属性是真还是假,那么是否有正确的方法来模拟这样的东西?

最佳答案

使用界面IConnectionMultiplexer而不是具体类 ConnectionMultiplexer在你自己的类里面。

public interface ICacheable
{
   void DoYourJob();
}

public sealed class RedisCacheHandler : ICacheable
{
    private readonly IConnectionMultiplexer multiplexer;

    public RedisCacheHandler(IConnectionMultiplexer multiplexer)
    {
        this.multiplexer = multiplexer;
    }

    public void DoYourJob() 
    {
        var database = multiplexer.GetDatabase(1);

        // your code        
    }
}

然后您可以轻松地模拟和测试它:

// Arrange
var mockMultiplexer = new Mock<IConnectionMultiplexer>();

mockMultiplexer.Setup(_ => _.IsConnected).Returns(false);

var mockDatabase = new Mock<IDatabase>();

mockMultiplexer
    .Setup(_ => _.GetDatabase(It.IsAny<int>(), It.IsAny<object>()))
    .Returns(mockDatabase.Object);

var cacheHandler = new RedisCacheHandler(mockMultiplexer.Object);

// Act
cacheHandler.DoYourJob();


// Assert
// your tests

关于c# - 如何使用 Moq 模拟 StackExchange.Redis ConnectionMultiplexer 类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28325870/

相关文章:

c# - 这是通用委托(delegate)和事件的正确语法吗?

c# - 自定义配置部分 .NET

.net - 如何确定当前用户是否通过 .NET 中的终端服务登录?

javascript - 在Sinon中假调用具有特定参数的函数

c# - 如何使用 Nunit 断言每个集合项

c# - 简单快速的异步二进制 TCP 套接字服务器?

c# - .csproj 文件中的 ProductVersion 设置由什么控制?

.net - 使用 WCF RIA 服务,其中数据源不是经典(关系)数据库

.net - 检查 WMI ManagementObject 查询是否为 Nothing 而不是使用 Try/Catch?

java - 资源访问异常 : I/O error on POST request