리포지토리는 도메인에서 NHibernate 또는 Doctrine과 같은 DAL 프레임 워크 또는 SQL 실행 클래스로 변환됩니다. 즉, 저장소는 해당 프레임 워크에서 해당 작업을 수행하기 위해 메소드를 호출합니다. 저장소는 데이터를 가져 오는 데 필요한 쿼리를 구성합니다. ORM 프레임 워크를 사용하지 않는 경우 (당신의 희망은 ...), 저장소는 원시 SQL 문이 작성되는 장소가됩니다.
이러한 방법 중 가장 기본적인 방법은 저장입니다. 대부분의 경우 이는 단순히 저장소에서 작업 단위 (또는 세션)로 오브젝트를 전달합니다.
public void Save(Car car)
{
session.Save(car);
}
그러나 ID로 자동차를 가져 오는 것과 같은 다른 예를 살펴 보겠습니다. 다음과 같이 보일 수 있습니다
public function GetCarWithId(String id)
{
return Session.QueryOver<Car>()
.Where(x => x.Id == id)
.SingleOrDefault();
}
여전히 복잡하지는 않지만 여러 조건으로 상상할 수 있습니다 ( 'Volkswagen'그룹의 모든 브랜드에 대해 2010 년 이후에 만들어진 모든 자동차를 가져 오십시오). 따라서 진정한 TDD 방식으로이를 테스트해야합니다. 이를 수행하는 몇 가지 방법이 있습니다.
옵션 1 : ORM 프레임 워크에 대한 호출을 조롱
물론 Session 개체를 조롱하고 올바른 호출이 이루어 졌다고 간단히 주장 할 수 있습니다. 이것은 저장소를 테스트하는 동안 저장소가 원하는 방식으로 내부적으로 보이는지 테스트하기 때문에 실제로 테스트 중심 이 아닙니다 . 테스트는 기본적으로 '코드는 다음과 같아야합니다'라고 말합니다. 여전히 유효한 접근 방법이지만 이러한 종류의 테스트에는 가치가 거의 없다고 생각합니다.
옵션 2 : 테스트에서 데이터베이스를 (다시) 빌드
일부 DAL 프레임 워크에서는 도메인을 테이블에 매핑하기 위해 만든 매핑 파일을 기반으로 데이터베이스의 전체 구조를 구축 할 수 있습니다. 이러한 프레임 워크의 경우 리포지토리를 테스트하는 방법은 테스트의 첫 단계에서 메모리 내 데이터베이스로 데이터베이스를 만들고 DAL 프레임 워크를 사용하여 개체를 메모리 내 데이터베이스에 추가하는 것입니다. 그런 다음 인 메모리 데이터베이스의 저장소를 사용하여 메소드가 작동하는지 테스트 할 수 있습니다. 이 테스트는 느리지 만 매우 유효하며 테스트를 주도합니다. DAL 프레임 워크와의 협조가 필요합니다.
옵션 3 : 실제 데이터베이스에서 테스트
또 다른 방법은 실제 데이터베이스를 테스트하고 단위 테스트를 분리하는 것입니다. 트랜잭션으로 테스트를 둘러싸고, 수동으로 정리하고 (유지하기가 매우 권장되지는 않음), 각 단계 후에 데이터베이스를 완전히 다시 빌드하십시오 ... 빌드하는 애플리케이션에 따라 가능하지 않다. 내 응용 프로그램에서 소스 제어에서 로컬 개발 데이터베이스를 완벽하게 구축 할 수 있으며 리포지토리의 단위 테스트는 트랜잭션을 사용하여 테스트를 서로 완전히 분리합니다 (오픈 트랜잭션, 데이터 삽입, 테스트 리포지토리, 롤백 트랜잭션). 모든 빌드는 먼저 로컬 개발 데이터베이스를 설정 한 다음 해당 로컬 개발 데이터베이스의 리포지토리에 대한 트랜잭션 격리 단위 테스트를 수행합니다. 그것'
DAL을 테스트하지 마십시오
NHibernate와 같은 DAL 프레임 워크를 사용하는 경우 해당 프레임 워크를 테스트 할 필요가 없습니다. 도메인 객체를 저장, 검색 및 비교하여 모든 것이 정상인지 확인하기 위해 매핑 파일을 테스트 할 수 있지만 (캐싱을 비활성화해야 함) 작성해야 할 다른 많은 테스트만큼 필요하지는 않습니다. 나는 아이들에 대한 조건을 가진 부모의 컬렉션에 주로 이것을하는 경향이 있습니다.
리포지토리의 반환을 테스트 할 때 도메인 개체의 일부 식별 속성이 일치하는지 간단히 확인할 수 있습니다. 이것은 ID 일 수 있지만 테스트에서 사람이 읽을 수있는 속성을 확인하는 것이 더 유리합니다. '2010 년 이후에 만든 모든 차를 가져 오십시오.'에서 이것은 단순히 5 대의 차가 반환되고 번호판이 '여기에 목록 삽입'인지 확인합니다. 추가 이점은 정렬에 대해 생각하게하고 테스트가 자동으로 정렬을 강제한다는 것입니다. 여러 번 정렬 (데이터베이스에서 정렬 된 반환, 뷰 객체를 만들기 전에 정렬 한 다음 뷰 객체를 모두 동일한 경우에 같은 경우에 정렬)하는 응용 프로그램이 몇 개인 지 또는 놀랍게도 저장소 정렬을 가정하고 실수로 제거 하는 응용 프로그램 수에 놀랄 것입니다. UI를 깨고 길을 따라 일부.
'단위 테스트'는 단지 이름입니다
제 생각에 단위 테스트는 대부분 데이터베이스에 영향을 미치지 않아야 합니다. 소스의 데이터를 필요로하는 모든 코드가 저장소에서이를 수행하고 해당 저장소가 종속성으로 삽입되도록 응용 프로그램을 빌드합니다. 이를 통해 쉽게 조롱하고 원하는 모든 TDD 장점을 얻을 수 있습니다. 그러나 결국 당신은 당신의 저장소가 그들의 의무를 수행하고 있는지 확인하기를 원하며, 가장 쉬운 방법이 데이터베이스에 도달한다면, 그렇게하십시오. 나는 '단위 테스트가 데이터베이스에 닿아서는 안된다'는 개념을 오랫동안 버려두고 이것을해야 할 진짜 이유가 있다는 것을 배웠다. 그러나 자동 및 반복적 으로이 작업을 수행 할 수있는 경우에만. 그리고 우리가 그러한 테스트를 '단위 테스트'또는 '통합 테스트'라고 부르는 날씨는 헛소리입니다.