[英]How can I mock the Azure Redis Cache?
How can I mock the Azure Redis Cache? 如何模拟Azure Redis缓存?
I would like to write unit test for one of my application which uses Azure Redis Cache. 我想为使用Azure Redis缓存的应用程序之一编写单元测试。 Since I am completely new to mocking and stubbing in writing unit test code, I am looking for help in how I can start with the basic script for mocking/stubbing cache component.
由于我对编写单元测试代码中的模拟和存根是完全陌生的,因此我正在寻求有关如何从基本脚本开始进行模拟/存根缓存组件的帮助。
Testing with external resources like databases, files, and caches is integration testing, non unit . 使用外部资源(例如数据库,文件和缓存)进行的测试是集成测试,非单元 。 What you can test in unit-tests is the fact, that your code is calling caching methods.
您可以在单元测试中进行测试的事实是,您的代码正在调用缓存方法。
So, first, you need an interface of cache service . 因此,首先,您需要一个cache service接口。 This interface not only let you test your code, but also let you use different caching servers.
该接口不仅可以测试代码,还可以使用其他缓存服务器。
public interface ICache
{
void Add<T>(string key, TimeSpan lifetime, T value);
bool TryGet<T>(string key, out T value);
void Remove(string key);
. . .
}
Second, you need domain code to test: 其次,您需要域代码进行测试:
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);
}
}
Third, let's make stub cache: 第三,让我们进行存根缓存:
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;
}
. . .
}
And finally you can write unit-test: 最后,您可以编写单元测试:
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);
}
Well, you've checked that the method ConfirmNotSleeping
calls the method Add
. 好了,您已经检查了方法
ConfirmNotSleeping
调用了方法Add
。
Now, you should implement ICache
for Redis: 现在,您应该实现
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;
}
. . .
}
To simplify implement stubs and mocks you can use libraries like Moq . 为了简化实现存根和模拟,可以使用Moq之类的库。 These libraries let you automatically generate stubs and mocks for your purpose.
这些库使您可以根据自己的目的自动生成存根和模拟。 So you test code will look like this:
因此,您的测试代码将如下所示:
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.