繁体   English   中英

如何模拟Azure Redis缓存?

[英]How can I mock the Azure Redis Cache?

如何模拟Azure Redis缓存?

我想为使用Azure Redis缓存的应用程序之一编写单元测试。 由于我对编写单元测试代码中的模拟和存根是完全陌生的,因此我正在寻求有关如何从基本脚本开始进行模拟/存根缓存组件的帮助。

使用外部资源(例如数据库,文件和缓存)进行的测试是集成测试,非单元 您可以在单元测试中进行测试的事实是,您的代码正在调用缓存方法。

因此,首先,您需要一个cache service接口。 该接口不仅可以测试代码,还可以使用其他缓存服务器。

public interface ICache
{
    void Add<T>(string key, TimeSpan lifetime, T value);

    bool TryGet<T>(string key, out T value);

    void Remove(string key);

    . . .
}

其次,您需要域代码进行测试:

public class SleepingMembersService
{
    private readonly TimeStamp _lifetime = TimeStamp.FromMinutes(5);
    private readonly ICache _cache;
    private readonly INotifier _notifier;

    public SleepingMembersService(ICache cache, INotifier notifier)
    {
        _cache = cache;
        _notifier = notifier;
    }

    private string MakeKey(User user) => $"unsleepingUser{user.Id}";

    public void WakeUpIfSleep(IUser user)
    {
        var key = MakeKey(user);
        bool isWaking;
        if (_cache.TryGet(key, out isWaking) && isWaking)
            return;

        notifier.Notify(user.Id, "Wake up!");            
    }

    public void ConfirmImNotSleeping(IUser user)
    {
        var key = MakeKey(user);
        _cache.Add(key, _lifeTime, true);
    }
}

第三,让我们进行存根缓存:

public class StubCache : ICache
{
    public bool TryGetResult { get; set; }

    public bool TryGetValue { get; set; }

    public bool AddValue { get; set; }

    public TimeStamp LifeTimeValue { get; set; }

    void Add<T>(string key, TimeSpan lifetime, T value)
    {
        LifeTimeValue = lifetime;
        AddValue = (bool)(object)value;
    }

    bool TryGet<T>(string key, out T value)
    {
        value = (T)(object)TryGetValue;
        return TryGetResult;
    }

    . . .
}

最后,您可以编写单元测试:

pubic void ConfirmImNotSleeping_WhenCalled_CallsAdd()
{
    var cache = new StubCache<bool>();
    var notifier = new StubNotifier();
    var service = new SleepingMembersService(cache, notifier);
    var user = new StubUser(1, "John Doe");

    service.ConfirmNotSleeping(user);

    Assert.IsTrue(cache.AddValue);
}

好了,您已经检查了方法ConfirmNotSleeping调用了方法Add

现在,您应该实现ICache for Redis:

public RedisCache : ICache
{
    private IConnectionMultiplexer connection;

    public bool TryGet<T>(string key, out T value)
    {
        var cache = Connection.GetDatabase();

        var rValue = cache.StringGet(key);
        if (!rValue.HasValue)
        {
            value = default(T);
            return false;
        }

        value = JsonConvert.DeserializeObject<T>(rValue);
        return true;
    }

    . . .    
}

为了简化实现存根和模拟,可以使用Moq之类的库。 这些库使您可以根据自己的目的自动生成存根和模拟。 因此,您的测试代码将如下所示:

pubic void ConfirmImNotSleeping_WhenCalled_CallsAdd()
{
    var cacheStub = new Mock<ICache>();
    var notifierStub = new Mock<INotifier>();
    var service = new SleepingMembersService(cache.Object, notifier.Object);
    var userStub = new Mock<IUser>();

    service.ConfirmNotSleeping(user.Object);

    cacheStub.Vertify(x => x.Add(It.IsAny<string>(), It.IsAny<TimeStamp>(), true));
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM