2015-02-04 3 views
2

나는 Redis 데이터베이스에 연결하기 위해 StackExchange.Redis 라이브러리를 사용하고자하는 프로젝트에 참여하고 있습니다. 또한 단위 테스트에서 모의 ​​라이브러리에 Moq을 사용하고 싶지만 해결하기 위해 도움이 필요한로드 블록을 실행 중입니다.Moq를 사용하여 StackExchange.Redis 라이브러리가 던진 예외를 시뮬레이트하는 방법은 무엇입니까?

내 특정 문제는 내가 명령/응답 아키텍처를 가지고 있으며 응답을 반환하기 위해 실제 작업을 수행하기 전에 명령이 캐시에서 만족 될 수 있는지 확인하는 캐시 "래퍼"를 테스트하려고합니다. 중요한 고려 사항은 캐시 오류로 인해 요청이 처리되지 않아야하기 때문에 StackExchange에 대한 특정 실패를 조롱하길 바랍니다. IDatabase 인터페이스. 그러나, 나는 조롱 한 객체에서 RedisException을 던지는 방법을 알아낼 수 없습니다. 예를 들어, 다음 코드를 사용하고 싶지만이 라이브러리가 던진 예외에 대한 공용 생성자가 없으므로 컴파일되지 않습니다.

Mock<IDatabase> _mockCache = new Mock<IDatabase>(); 

    // Simulate a connection exception to validate how the cache layer handles it 
    // THIS DOESN'T COMPILE THOUGH 
    // 
    _mockCache.Setup(cache => cache.StringGetAsync("a", CommandFlags.None)).Throws<RedisException>(); 

StackExchange.Redis 라이브러리 내에서 실패를 조롱하는 더 좋은 방법이 있습니까? Moq 또는이 라이브러리에 대해 테스트하는 방법 중 하나가 확실하지 않은 것 같습니다.

답변

2

당신은 항상 생성자를 실행하지 않고 클래스의 인스턴스를 생성 FormatterServices.GetUninitializedObject를 사용할 수 있습니다

지정된 객체의 형태의 새로운 인스턴스를 생성합니다.

개체의 새 인스턴스가 0으로 초기화되고 생성자가 실행되지 않으므로 개체가 해당 개체에 의해 유효한 것으로 간주되는 상태를 나타내지 않을 수 있습니다. 현재 필드는 사용자가 모든 필드를 즉시 채우려는 경우 비 직렬화에만 사용해야합니다. immutable 타입의 빈 인스턴스를 생성하는 것은 목적이 없으므로 초기화되지 않은 문자열을 생성하지 않습니다.

그래서 설정은 다음과 같이 수 :

var e = (RedisException)FormatterServices.GetUninitializedObject(typeof(RedisException)); 

Mock<IDatabase> _mockCache = new Mock<IDatabase>(); 
_mockCache.Setup(cache => cache.StringGetAsync("a", CommandFlags.None)).Throws(e); 

조금 hackish입니다; 생성자가 실행되지 않으므로 RedisException 인스턴스의 유효한 상태에 의존하면 안됩니다.

+0

내가 필요한 것에 적합합니다. * FormatterServices *를 알지 못해서 고마워요! –

관련 문제