我正在努力模拟与 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);
但是,虽然该代码编译得很好,但在运行测试时出现此错误:
我也尝试模拟多路复用器类本身,并将其提供给我的模拟缓存,但我遇到了多路复用器类是密封的事实:
_mockCache = new Mock<IDatabase>();
var mockMultiplexer = new Mock<ConnectionMultiplexer>();
mockMultiplexer.Setup(c => c.IsConnected).Returns(false);
_mockCache.Setup(cache => cache.Multiplexer).Returns(mockMultiplexer.Object);
...但这会导致此错误:
最终我想在我的测试中控制该属性是真还是假,那么是否有正确的方法来模拟这样的东西?
最佳答案
使用界面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/