사용 의존성 주입 단위 테스트 (DI) 필수을?
코드를 격리하는 또 다른 대안을 생각할 수 없으므로 테스트 할 수 있습니다. 또한 내가 본 모든 예제는이 패턴을 사용합니다. 이것이 유일하게 실행 가능한 옵션이거나 다른 대안이 있습니까?
사용 의존성 주입 단위 테스트 (DI) 필수을?
코드를 격리하는 또 다른 대안을 생각할 수 없으므로 테스트 할 수 있습니다. 또한 내가 본 모든 예제는이 패턴을 사용합니다. 이것이 유일하게 실행 가능한 옵션이거나 다른 대안이 있습니까?
답변:
DI는 단위 테스트를 훨씬 쉽게 해줍니다. 그러나 DI 없이도 단위 테스트를 작성할 수 있습니다. DI가 널리 퍼지기 전에 많은 단위 테스트가 이미 작성되었습니다. (물론, 이러한 기술 중 일부는 DI라는 이름과 동일하거나 매우 유사합니다. :-)
DI에 대해 배우기 전에 인터페이스와 팩토리를 많이 사용했습니다. 실제 팩토리 클래스 이름은 구성 파일에서 읽거나 인수로 SUT에 전달되었을 수 있습니다.
다른 방법은 싱글 톤 (또는 일반적으로 전 세계적으로 액세스 가능한 데이터)을 사용하는 것입니다. 그렇습니다. 일반적으로 자신을 포함하여 많은 사람들이 권장하지 않는다는 것을 알고 있습니다. 또 그 수도 싱글 테스트 케이스 특정 아닌 정적 구성 데이터를 포함하지만, 생산 및 시험 환경 다르기 특히, 특정 상황에서 실행 가능. 물론 알려진 문제가 있으므로 사용할 수 있으면 DI가 우수합니다. 그러나 종종 (예를 들어 레거시 시스템에서) 할 수 없습니다.
그중 이야기 레거시 코드와 함께 효과적으로 작동 트릭을 많이 설명하는 것은 테스트에 포함 레거시 코드를 얻을 수 있습니다. 이들 중 많은 부분이 좋지 않고 장기적인 해결책이 아닙니다. 그러나 다른 방법으로는 테스트 할 수없는 시스템에 대한 첫 번째 유용한 단위 테스트를 만들 수 있습니다. 리팩토링을 시작할 수 있으며 결국 DI를 도입 할 수 있습니다.
사용중인 기술에 따라 DI를 사용하지 않고도 종속성을 격리 할 수 있습니다. 예를 들어, .NET 세계에서 Moles를 사용하면 DI 패턴없이 종속성을 격리 할 수 있습니다.
즉, 이러한 격리 프레임 워크는 외부 종속성 (파일 시스템, 데이터베이스 등)이있는 코드의 상황을 위해 작성되었으며 의도 된 것입니다. 즉, 이것을 할 수 있다는 사실이 그 또는 그녀가해야한다는 것을 의미하지는 않습니다.
의존성 주입은 단위 테스트를 허용하지만 해당 객체의 코드를 변경하지 않고도 객체의 동작을 수정할 수 있습니다 (개방 / 폐쇄 원리). 따라서 테스트 가능한 코드 일뿐 아니라 유연한 코드가 생성됩니다. 일반적으로 유지 관리 가능 / 유연한 코드와 테스트 가능한 코드 사이에는 큰 상관 관계가 있음을 발견했습니다.
아니요 , 의존성 주입은 단위 테스트에 필수적이지 않습니다.
의존성 주입은 일부 하위 처리를 수행하기 위해 종속 클래스 인스턴스가 필요한 클래스가있는 경우 도움이됩니다. DI 대신 비즈니스 방법의 논리를 단위 테스트 할 수없는 데이터 연결 부분과 단위 테스트 할 수있는 계산 부분으로 분리 할 수 있습니다.
예 (DI 사용)이 구현은 Employee, Account, ...에 따라 다릅니다.
bool hasPermissionToTransferMoney(Employee employee, Account from, Account to, Money amount)
{
if (amount > 100 && employee.isStudent())
return false;
if (to.getOwner().getFamiliyName() == employee.getFamilyName() && ...
return false; // cannot transfer money to himself;
...
}
데이터 수집 및 계산 분리 후 :
bool hasPermissionToTransferMoney(Employee employee, Account from, Account to, Money amount)
{
return hasPermissionToTransferMoney(employee.isStudent(), employee.getFamilyName(), to.getOwner().getFamilyName(), ...);
}
// the actual permission calculation
static bool hasPermissionToTransferMoney(boolean isStudent, string employeeFamilyName, string receiverFamilyName, ...)
if (amount > 100 && isStudent)
return false;
if (receiverFamilyName == employeeFamiliyName && ...
return false; // cannot transfer money to himself
...
}
의존성 주입없이 계산 부분을 쉽게 테스트 할 수 있습니다.
예, 절연을 위해 DI를 사용하는 것에 대한 대안이 있습니다.
하나의 대안은 실제 객체 대신 모의 객체를 반환하도록 테스트에서 구성 할 수있는 팩토리 또는 ServiceLocator를 사용하는 것입니다.
또 다른 방법은 적절한 격리 프레임 워크 또는 조롱 도구를 사용하는 것입니다. 이러한 도구는 거의 모든 현대 프로그래밍 언어 (Java, C #, Ruby 및 Python의 경우)에 존재합니다. 테스트 된 클래스가 종속성을 직접 인스턴스화하더라도 다른 클래스 / 유형의 구현에서 테스트중인 클래스를 분리 할 수 있습니다.