문제

프로파일 러 보고서에서 의존성 주입으로 모의 기반 테스트 결과를 점점 더 많이보고 있습니다. 많은 의존성이 정적 이었지만, 방법을 분리하여 테스트하려면 다음 예제와 같이 인스턴스 멤버로 변경됩니다.

class ShortLivedThing {
   IDependency1 dep1;
   IDependency1 dep2;
   IDependency1 dep3;
   ...

   int TheRealData;

   // Constructor used in production 
   public ShortLivedThing() {
     dep1 = new Dep1(); dep2 = new Dep2(); dep3 = new Dep3();
   }

   // DI for testing 
   public ShortLivedThing(IDependency1 d1, IDependency2 d2, IDependency3 d3) { 
     dep1 = d1(); dep2 = d2(); dep3 = d3();
   }
}

결국 종속성에는 대부분의 시간에는 다른 종속성이 있습니다. 이로 인해 (주로 "정적") 객체의 트리가 인스턴스화됩니다. 매번 메소드 호출은 테스트 외부에서 수행됩니다. 각 물체는 매우 작지만 (몇 개의 포인터) 트리 효과는 이것을 점점 더 많은 성능 히트로 바꿉니다.

우리는 그것에 대해 무엇을 할 수 있습니까?

도움이 되었습니까?

해결책

적절한 의존성 분사 프레임 워크가 제공 할 수있는 기능을 활용 해야하는 것처럼 보입니다. 테스트/생산에 다른 건축 로직을 사용하지 마십시오.

봄의 경우 싱글 톤 주입은 컨테이너 스타트 업에서만 수행됩니다. 프로토 타입 주입은 매번 수행됩니다. 전체 배선은 유닛 테스트를 실행할 때마다, 유선이 연결된 경우에도 수행됩니다. 따라서 프로파일 링 단위 테스트는 일반적으로 좋은 생각이 아닙니다.

어쩌면 당신은 너무 적은 싱글 톤 스코프와 너무 많은 프로토 타입 범위를 사용하고 있습니까? (프로토 타입 = 매번 새 인스턴스)

스프링 주입의 좋은 점은 스코프 프록시를 사용할 수 있다는 것입니다. 즉, 객체 그래프가 다음과 같이 보일 수 있습니다.

 A Singleton
 |
 B Singleton
 |
 C Prototype (per-invocation)
 |
 D Singleton
 |
 E Session scope (web app)
 |
 F Singleton

각 요청은 세션 당 1 인스턴스와 E 인스턴스 인 인스턴스 만 생성합니다. A, B, D 및 F는 싱글 톤입니다. 웹 앱이 아닌 경우 기본적으로 세션 범위가 없지만 사용자 정의 범위를 만들 수도 있습니다 (창 "스코프는 윈도우 데스크탑 앱의 경우 멋진 사운드를 시원하게합니다). 여기서 단서는 어떤 레벨에서든 스코프를 "소개 할 수있다"는 것입니다. 효과적으로 10 개의 싱글 톤 객체를 가질 수 있으며 갑자기 세션 스코프가 나타나는 모든 것이 나타납니다. (이것은 계층 구조에서 크로스 컷팅 기능을 구현하는 방법을 실제로 혁명 할 수 있지만 다른 이야기입니다).

이것은 실제로 DI 모델 내에서 최소 객체 생성을 가능하게합니다.

이것은 Java의 스프링이지만 다른 여러 DI 프레임 워크가 유사한 기능을 지원해야한다고 생각합니다. 아마도 가장 미니멀 한 것이 아닐 수도 있습니다.

다른 팁

나는 당신이 "di 생성자"만 있어야한다고 생각합니다. 생산뿐만 아니라 테스트를 위해이 생성자를 호출합니다.

class ShortLivedThing {
   IDependency1 dep1;
   IDependency1 dep2;
   IDependency1 dep3;
   ...

   int TheRealData;

   public ShortLivedThing(IDependency1 d1, IDependency2 d2, IDependency3 d3) { 
     dep1 = d1; dep2 = d2; dep3 = d3;
   }
}

이렇게하면 테스트 외부에서 메소드 호출이 수행 될 때마다 객체 트리를 인스턴스화하는 데 문제가 없습니다. 물론 생산을 위해서는 물체를 올바르게 연결해야합니다. 밖의 참여하는 대상 자체는 좋은 일입니다.

요약 : 50% DI / 50% 하드 코딩을하지 마십시오. 100% DI를 찾으십시오.

우려가 느린 테스트 인 경우 동시에 실행 해보고 테스트 프로세스가 프로그래머를 방해하지 않도록하십시오.

이 프로세스 자동화 :

  • 어떤 사람이 체크인하면 저장소에서 빌드를 만듭니다.
  • 이 빌드에서 테스트를 실행하십시오.
  • E- 체크인 한 개발자에게 결과를 우편으로 보내십시오.

첫 번째 체크인이 실제 저장소에 완료되지 않으면 더 좋습니다. 임시로 만들고 이것으로 빌드를 만들어냅니다. 선택적으로 성능 테스트, 스타일 점검 등을 수행 할 수 있으며 E -Mail에 포함시킬 수 있습니다. 이렇게하면 자동화 된 프로세스에 한 단계를 추가하십시오.

  • 테스트가 통과되고 선택 사항 기준이 충족되면 새 코드를 실제 저장소와 병합하십시오.

이런 식으로 느린 테스트는 걱정이 아닙니다. 또한 개발자가 자신의 코드가 무언가를 깨뜨 렸는지 또는 예상되는 성능을 높이는 지 알아야 할 때, 그녀는 체크인하고 그녀를 위해 생성 된 E- 메일을 기다립니다.

참조를 통과하는 것은 어떻습니까?

내가 생각해 낼 수있는 최선은 모든 종속성을 하나의 "컨텍스트"객체에 넣고 모든 인스턴스 사이에서 공유하는 것입니다. 이것은 성능 문제를 다소 완화시켜야합니다.

.NET을 타겟팅하는 경우 Autofac. 그것은 생성 측면을 조정하고 자원 사용을 막기위한 결정 론적 처분을 위해 다양한 범위 (싱글 톤, 공장, 컨테이너)를 가지고 있으며, 생성 된 변형 및 lambda 표현식을 사용하여 구성 요소를 구성하고 반사 비용을 피할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top