2

我正在做一个项目,我想使用 StackExchange.Redis 库连接到 Redis 数据库。此外,我想在我们的单元测试中使用 Moq 作为模拟库,但我遇到了一个障碍,我需要一些帮助来解决。

我的具体问题是,我有一个命令/响应架构,并且我正在尝试测试一个缓存“包装器”,该缓存“包装器”在执行实际工作以返回响应之前检查缓存是否可以满足命令。一个重要的考虑因素是缓存故障不应该停止处理请求,因此我想模拟 StackExchange.Redis IDatabase接口的某些故障。但是,我似乎无法弄清楚如何从我的模拟对象中抛出 RedisException。例如,我想只使用下面的代码,但它不能编译,因为这个库抛出的异常没有公共构造函数。

    Mock<IDatabase> _mockCache = new Mock<IDatabase>();

    // Simulate a connection exception to validate how the cache layer handles it
    //  THIS DOESN'T COMPILE THOUGH
    //
    _mockCache.Setup(cache => cache.StringGetAsync("a", CommandFlags.None)).Throws<RedisException>();

有没有更好的方法来模拟 StackExchange.Redis 库中的故障?我觉得我在 Moq 或如何针对这个库进行测试时遗漏了一些明显的东西。

4

1 回答 1

2

您始终可以FormatterServices.GetUninitializedObject在不运行任何构造函数的情况下创建类的实例:

创建指定对象类型的新实例。

因为对象的新实例被初始化为零并且没有运行构造函数,所以该对象可能不代表该对象认为有效的状态。当前方法仅应在用户打算立即填充所有字段时用于反序列化。它不会创建未初始化的字符串,因为创建不可变类型的空实例没有任何意义。

因此,您的设置可能如下所示:

var e = (RedisException)FormatterServices.GetUninitializedObject(typeof(RedisException)); 

Mock<IDatabase> _mockCache = new Mock<IDatabase>();
_mockCache.Setup(cache => cache.StringGetAsync("a", CommandFlags.None)).Throws(e);

这有点骇人听闻;由于没有运行构造函数,因此您不应依赖RedisException实例的有效状态。

于 2015-02-04T09:30:58.517 回答