2012-04-03 3 views
1

유닛 테스트를하고 싶은 일부 클래스 (클래스 A라고 함)가 있지만 일부 정적 메소드에서는 클래스 B (클래스 B라고 함)를 사용합니다. 유닛 테스팅 C# 리팩터링 정적 메소드

내가 인스턴스 메서드하고 A 클래스에 주입하도록 리팩토링해야 정적 방법과 이러한 클래스에 대한 참조를 제거하려면

문제는 클래스 A 서비스를 많이 (뿐만 아니라 클래스 B)의이 의존하는 것 같다가있다 에?

이 시나리오에서 가장 좋은 옵션은 무엇입니까? 이러한 서비스를 수용 할 수있는 많은 매개 변수를 가진 생성자가 있습니까?

또는 클래스 A에 너무 많은 종속성이 있다는 사실이 내 설계에 문제가 있습니까?

감사

+0

종속성 문제와 나쁜 디자인 벡을 당신은 그들을 주사 할 수 없습니다. 의미에서의 서비스? 웹 서비스? Windows 서비스? – Zenwalker

+0

최선의 선택 : 독점 책임과 솔리드에 대해 읽으십시오 ... 아 그래 : FAQ도 읽고 우리에게 몇 가지 코드를 보여주십시오 ... – Carsten

답변

5

문제는 클래스 A는이에 따라 달라 보인다 서비스를 많이 (뿐만 아니라 클래스 B)가 무엇입니까?

일반적으로 몇 가지 종속성은 코드 냄새를 나타냅니다. 귀하의 클래스는 단일 책임 원칙을 위반할 가능성이 큽니다.

작은 클래스로 분류 해보십시오.

단위 테스트는 좋은 품질 지표입니다. 테스트하기 어려운 클래스는 종종 하나 이상의 솔리드 원칙을 위반합니다.

이 시나리오에서 가장 좋은 옵션은 무엇입니까? 이러한 서비스에 사용할 수있는 많은 매개 변수가있는 생성자가 있습니까?

생성자 주입은 항상 클래스의 종속성을 알기 쉽기 때문에 항상 선호됩니다.

2

특히 Unity 또는 Ninject와 같은 Dependency Injection 프레임 워크를 사용하는 경우에만 주입 할 의존성이 많은 경우 생성자 삽입을 권장합니다. 어디에서나 생성자 삽입을 추가하기 위해 기존 코드베이스를 리팩토링하는 것은 대개 지저분한 일이며 아마도 모든 기본 클래스의 모든 서비스를 로컬 변수에 저장해야 체인 아래의 클래스에 전달할 수 있습니다.

IService _service = ServiceLocator.GetService<IService>(); 

이 필요합니다 :이 경우에 어떻게 할 것인지

당신이 당신의 비 정적 서비스에 액세스 할 수있는 단일 정적 ServiceLocator/컨테이너 클래스의 ServiceLocator 패턴의 일부 구현을 사용하다 기존 코드의 리팩토링의 최소 금액 (다만 _service.DoSomething()MyService.DoSomething()을 대체하고, 아직도 당신이 조롱과 ServiceLocator의 인터넷 모음 교체하여 코드를 테스트 할 수 있습니다 :

ServiceLocator.Register<IService>(myFakeService); 
+0

ServiceLocator 패턴을 사용하는 imho는 모든 의존성이 숨겨져 있기 때문에 더 큰 혼란을 만듭니다. 또한 앞으로 필요한 리팩토링을 추진할 것입니다 (기다릴수록 리팩토링이 더 비쌉니다). 리팩토링하지 않으면 유지 보수가 악몽이됩니다. – jgauffin