2016-08-03 34 views
0

Wie kann ich den Azure Redis Cache verspotten?Wie kann ich den Azure Redis Cache verspotten?

Ich möchte Komponententest für eine meiner Anwendung, die Azure Redis Cache verwendet, schreiben. Da ich im Schreiben von Unit-Test-Code völlig neu bin, um zu spotten und zu stubben, suche ich nach Hilfe, wie ich mit dem grundlegenden Skript für spottende/stubbing Cache-Komponente beginnen kann.

Antwort

2

Testing mit externen Ressourcen wie Datenbanken, Dateien und Caches ist Integration Tests, nicht Einheit. Was Sie in Unit-Tests testen können, ist die Tatsache, dass Ihr Code Caching-Methoden aufruft.

Also, zuerst benötigen Sie eine Schnittstelle von Cache-Service. Mit dieser Schnittstelle können Sie nicht nur Ihren Code testen, sondern auch verschiedene Caching-Server verwenden.

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

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

    void Remove(string key); 

    . . . 
} 

Zweitens müssen Sie Domain-Code zu testen:

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); 
    } 
} 

Drittens wollen wir Stub Cache machen:

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; 
    } 

    . . . 
} 

Und schließlich können Sie Unit-Test schreiben:

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); 
} 

Nun, Sie haben die Methode überprüft ConfirmNotSleeping ruft die Methode Add auf.

Jetzt sollten Sie ICache für Redis implementieren:

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; 
    } 

    . . .  
} 

Zur Vereinfachung der Stubs zu implementieren und verhöhnt Sie Bibliotheken wie Moq verwenden können. Mit diesen Bibliotheken können Sie automatisch Stubs und Mocks für Ihren Zweck generieren. So testen Sie Code wie folgt aussehen:

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)); 
} 
+0

Vielen Dank für Ihre Hilfe! Aber der dritte Schritt ist Kompilierung Fehler in - void Add (String Schlüssel, TimeSpan Lebensdauer, T-Wert) { LifeTimeValue = Lebenszeit; AddValue = Wert; } Aufgrund der Art des Wertes ist T. –

+0

Es wäre toll, wenn Sie ein einfaches Beispiel von Set geben und ein Objekt aus Redis-Cache und anschließend den Testcode erhalten könnten. Vielen Dank! –

+0

Ich habe den Fehler bei der Implementierung der Methoden 'Add' und' TryGet' korrigiert. In Bezug auf Ihren zweiten Kommentar: Meine Antwort beschreibt die Einheit Testzyklus der Cache-Logik. Wenn Sie Redis-Methoden in Tests aufrufen möchten, wird es Integrationstests geben, keine Einheit. –