2016-08-03 7 views
0

Azure Redis Cache를 조롱 할 수 있습니까?Azure Redis Cache를 조롱하려면 어떻게해야합니까?

Azure Redis Cache를 사용하는 응용 프로그램 중 하나에 대한 단위 테스트를 작성하고 싶습니다. 필자가 단위 테스트 코드 작성을 완전히 조롱하고 스터 빙하는 것이 처음이므로 캐시 구성 요소를 조롱하거나 스터 빙하기위한 기본 스크립트로 시작할 수있는 방법에 대한 도움을 찾고 있습니다.

답변

2

데이터베이스, 파일 및 캐시와 같은 외부 리소스를 사용한 테스트는 통합통합 단위입니다. 단위 테스트에서 테스트 할 수있는 것은 코드가 캐싱 메서드를 호출한다는 사실입니다.

먼저, 캐시 서비스의 인터페이스가 필요합니다. 이 인터페이스는 코드를 테스트 할뿐만 아니라 다른 캐싱 서버를 사용할 수있게 해줍니다.

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

글쎄, 당신은 방법을 확인했습니다 ConfirmNotSleepingAdd 메서드를 호출합니다.

지금, 당신은 레디 스에 대한 ICache를 구현해야합니다 :

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

감사합니다. 그러나 세 번째 단계에서 컴파일 오류가 발생합니다. - void (문자열 키, TimeSpan 수명, T 값)을 추가하십시오. { LifeTimeValue = lifetime; AddValue = value; } 값 유형이 T입니다. –

+0

설정의 간단한 예제를 제공하고 Redis 캐시와 그 이후의 테스트 코드에서 개체를 얻을 수 있다면 좋을 것입니다. 감사! –

+0

메소드'Add'와'TryGet' 구현시 오류를 수정했습니다. 귀하의 두 번째 의견에 관해서는 : 내 대답은 캐시 논리의 단위 시험에 대해 설명합니다. 테스트에서 Redis 메서드를 호출하려면 단위가 아닌 통합 테스트가 필요합니다. –