0
我該如何模擬Azure Redis緩存?我該如何模擬Azure Redis緩存?
我想爲使用Azure Redis緩存的應用程序編寫單元測試。由於我在編寫單元測試代碼時嘲笑和寫作是全新的,因此我正在尋找關於如何開始使用基本腳本來模擬/存儲緩存組件的幫助。
我該如何模擬Azure Redis緩存?我該如何模擬Azure Redis緩存?
我想爲使用Azure Redis緩存的應用程序編寫單元測試。由於我在編寫單元測試代碼時嘲笑和寫作是全新的,因此我正在尋找關於如何開始使用基本腳本來模擬/存儲緩存組件的幫助。
使用外部資源(如數據庫,文件和緩存)進行測試是集成測試,非單元。你可以在單元測試中測試的事實是,你的代碼正在調用緩存方法。
所以,首先,你需要一個接口緩存服務。這個接口不僅可以讓你測試你的代碼,還可以讓你使用不同的緩存服務器。
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
對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));
}
謝謝你的幫助! 但是,第三步是給出編譯錯誤 - void Add(string key,TimeSpan lifetime,T value) LifeTimeValue = lifetime; AddValue = value; } 由於值的類型是T. –
如果您可以給出一個簡單的set示例並從Redis緩存中獲取對象並隨後獲得測試代碼,那將是非常棒的。謝謝! –
我糾正了方法'Add'和'TryGet'的執行錯誤。關於你的第二個評論:我的回答描述了緩存邏輯的單元問題。如果你想在測試中調用Redis方法,將會有集成測試,而不是單元測試。 –