2009-08-10 2 views
2

우리는 ASP.NET MVC 사이트를 구축하고 있으며, 단위 테스트를 가장 효과적으로 사용할 수있는 연결을 정의하는 데 어려움을 겪고 있습니다 (저는 '연결'을 일반적으로 사용합니다 - 세션, 연결, 어댑터 또는 트랜잭션 및 데이터베이스 작업을 관리 할 수있는 다른 유형의 데이터 컨텍스트). 우리는 UserService의 방법 내에서 이런 일을 할 거라고 과거MVC에서 데이터 컨텍스트 (어댑터, 연결, 세션 등)를 인스턴스화 할 위치는 어디입니까?

UserController 
UserService 
UserRepository 

:

의 우리가 3 개 클래스 있다고 가정 해 봅시다 그러나

Using (ISomeSession session = new SomeSession()) 
{ 
    session.StartTransaction(); 
    IUserRepository rep = new UserRepository(session); 
    rep.DoSomething(); 
    rep.Save(); 
    session.Commit(); 
} 

을, 정말 아니었다 SomeSession에 대한 의존성이 주입되지 않았으므로 단위 테스트가 가능합니다. 그러나, 우리가 D.I. UserService에 종속성을 주입하려면 UserService의 수명 동안 세션이 중단됩니다. UserController에서 호출 된 여러 서비스가있는 경우 각각의 세션은 UserController가 가비지 수집 될 때까지 매달려있을 수 있습니다.

더 나은 관리 방법에 대한 의견이 있으십니까? 나는 명백한 것을 놓치고 있는가?

편집

미안 분명하지 않다 경우 - 내가 세션/데이터 컨텍스트와 의존성 삽입 (Dependency Injection)을 사용할 수 있음을 이해하지만, 다음은 서비스 클래스의 수명 동안 유지되고 있어요. 실행 시간이 오래 걸리는 작업/메소드 (예 : 일괄 처리로 서비스를 호출한다고 가정 해 보겠습니다)의 경우 테스트 가능성을 추가하는 것 외에 다른 이유로 열린 세션이 많이 발생할 수 있습니다.

+1

실제 연결로 테스트하는 경우 단원 테스트가 아니라 통합 테스트입니다. – RichardOD

+0

Richard - 이해합니다.내 요점은 클래스의 수명 내내 연결 유지 (또는 최소한 컨텍스트 활성화)를 유지하지 않고 종속성을 클래스 수준으로 이동하는 방법을 알지 못했기 때문에 Using 문에서 약간의 시간 동안 . "Using"블록은 필요할 때 연결을 열고 완료되면 닫히기 때문에 훨씬 안전 해 보입니다. –

답변

2

RichardOD가 올바르게 관찰되었으므로 단위 테스트 작성에 라이브 데이터베이스 연결을 사용할 수 없습니다. 당신이 그것을하고 있다면, 당신은 통합 테스트입니다.

내 저장소 인터페이스, 실제 저장소 하나, 단위 테스트를위한 하나의 가짜 저장소에 대한 별도의 구현이 있습니다. 가짜 저장소는 실제 데이터 컨텍스트가 아닌 일반 목록에서 작동합니다. DI를 사용하여 올바른 저장소를 삽입 할 수 있습니다 (물건을 좀 더 편안하게 만들기 위해 Ninject를 사용하지만 손으로도 할 수 있습니다).

실제 연결로 단위 테스트를 수행하는 인스턴스가 거의 없지만 컨트롤러, UI 또는 비즈니스 계층 개체가 아닌 저장소 클래스의 단위 테스트입니다.

편집 : 덧글을 달았다면, 지금 당신이 실제로 무엇을 요구했는지 이해할 수있을 것 같습니다. 지난 주에 똑같은 주제로 작업했기 때문에 재미있는 점을 물어 보겠습니다.

매우 얇은 래퍼 내부에서 데이터 컨텍스트를 인스턴스화하고 컨텍스트를 HttpContext.Current.Items 사전에 배치합니다. 이 방법은 컨텍스트가 전역이지만 현재 요청에 대해서만 사용됩니다.

그래도 질문의 제목은 오해의 소지가 있습니다. 당신은 "유닛 테스팅을위한 데이터 컨텍스트를 어디서 인스턴스화 할 것인가"를 묻는 중이었습니다. 내 단위 테스트는 여전히 가짜 저장소에서 작동합니다.

+0

당신이 downvote면 괜찮아요,하지만 왜 이것이 사실인지 설명하는 것이 좋을 것입니다 ... –

+0

죄송합니다 ... 나는 응답해야합니다. 귀하의 대답은 정확하지만 그것이 내 질문에 대답하지 않았기 때문에 그것을 downvoted. 나는 D.I.을 이해합니다. 그리고 가짜 저장소를 만드는 방법. 문제는 컨텍스트가 저장소 외부에서 정의되고 다른 서비스/저장소 클래스에도 전달 될 수 있다는 것입니다 (즉, 트랜잭션에 참여할 수 있음). 컨텍스트의 수명은 서비스의 컨텍스트/연결을 인스턴스화 (또는 주입)하면 본질적으로 연결 상태를 일반적인 "Using (new context) {...} ". –

+0

아, 그래. 위의 편집을 참조하십시오 ... –

-2

가장 쉬운 방법은 web.config에서 개발 및 생산을 위해 정의한 Connectionstring을 사용하는 것입니다. Unittest의 경우 Testproject의 app.config에서 정의합니다.