매우 큰 레거시 프로젝트를 테스트하려고합니다.DI 컨테이너 대신 ThreadStatic을 사용하는 것이 잘못된 이유
우리는 대부분의 코드에서 사용하는 정적으로 사용할 수있는 서비스가 많이 있습니다. 문제는 이들을 조롱하기가 어렵다는 것입니다. 그들은 싱글 톤이었습니다. 이제는 가짜 단일체 - 동일한 정적 인터페이스이지만 함수는 전환 할 수있는 인스턴스 객체에 위임합니다. 이처럼 내 단위 테스트에서 지금
class ServiceEveryoneNeeds
{
public static IImplementation _implementation = new RealImplementation();
public IEnumerable<FooBar> GetAllTheThings() { return _implementation.GetAllTheThings(); }
}
:
void MyTest()
{
ServiceEveryoneNeeds._implementation = new MockImplementation();
}
지금까지 너무 좋아. 자극적 인면에서 우리는 단지 하나의 구현만을 필요로합니다. 그러나 테스트를 병렬로 실행하고 다른 모의 객체를해야 할 수도 있습니다, 그래서이 한 :
class Dependencies
{
//set this in prod to the real impl
public static IImplementation _realImplementation;
//unit tests set these
[ThreadStatic]
public static IImplementation _mock;
public static IImplementation TheImplementation
{ get {return _realImplementation ?? _mock; } }
public static void Cleanup() { _mock = null; }
}
그리고 다음을 : 그것은 모든 클래스에 이러한 서비스를 주입 생성자에 대규모 프로젝트이기 때문에 우리는이 길을 갔다
class ServiceEveryoneNeeds
{
static IImplementation GetImpl() { return Dependencies.TheImplementation; }
public static IEnumerable<FooBar> GetAllTheThings() {return GetImpl().GetAllTheThings(); }
}
//and
void MyTest()
{
Dependencies._mock = new BestMockEver();
//test
Dependencies.Cleanup();
}
그것은 그들을 필요로합니다. 동시에, 이들은 대부분의 기능이 의존하는 우리의 코드베이스 내의 보편적 인 서비스입니다.
이 패턴은 의존성을 숨기는 개념으로, 의존성을 명시 적으로 만드는 생성자 삽입과 반대되는 것으로 알고 있습니다.
혜택은 그러나 :
- 우리가 바로 단위 테스트를 시작, 대 3 개월 리팩터링하고 단위 테스트를 수행 할 수 있습니다.
- 우리는 여전히 전역 변수를 가지고 있지만 이것이 우리가 있었던 곳보다 엄격하게 더 나은 것처럼 보입니다.
우리의 의존성은 여전히 암묵적이지만, 나는이 접근법이 우리가 가진 것보다 엄격하게 우수하다고 주장 할 것입니다. 숨겨진 의존성을 제외하고, 적절한 DI 컨테이너를 사용하는 것보다 더 나쁜가? 어떤 문제에 빠지게 될까요?
아니요, 서비스 로케이터가 아닙니다. 이것은 주변 환경입니다. 사소한 차이점은 ServiceLocator가 모든 유형을 제공하도록 설계된 경우 유형이 잘 정의되어 있다는 점입니다.그리고 로컬 기본값이 있으므로 코드가 기본 동작없이 구성없이 실행되지만 로컬 기본 값을 바꿔 다른 동작을 얻을 수 있습니다. 올바른 상황에서 사용하면 좋지 않습니다. 상황이 매우 드물기는하지만. –
예, 기술적으로 당신은 절대적으로 옳습니다. 그러나 개인적으로 나는 주변 상황으로서 완전한 서비스를 언급하지 않을 것이다. Mark Seemann의'TimeProvider' 샘플은 작고 잘 정의 된 범위를 가지고 있습니다. 'ServiceEveryOneNeeds'는 ... 그렇게별로 들리지 않습니다. –