2009-03-27 5 views
1

다음 함수를 테스트하고 싶다고 가정 해 보겠습니다.아음속 지연로드 속성은 어떻게 단위 테스트합니까?

public void CancelOrder(Order order) 
{ 
    order.Status = "Cancelled"; 

    _emailService.SendEmail(order.User.Email, "Your order has been cancelled!"); 
} 

이제 Order 클래스는 SubSonic에서 생성 한 클래스이고 그 위에 User 속성은 지연로드되어 있습니다. 즉, order.User를 호출 할 때이를 의미합니다. 전자 메일로 실제로 SQL 문을 실행하여 사용자를 가져옵니다.

만약 내가 단위 테스트를 원한다면, 나는 정말로 내 단위 테스트가 내 데이터베이스를 치는 것을 원하지 않기 때문에 문제가있을 것이다.

내 현재 솔루션을 다음과 같이 CancelOrder 함수를 리팩토링 할 수 있습니다.

public void CancelOrder(Order order) 
{ 
    order.Status = "Cancelled"; 

    User user = _userRepository.GetByUserID(order.UserID); 

    _emailService.SendEmail(user.Email, "Your order has been cancelled!"); 
} 

그런 다음 _customer 개체를 반환하도록 _userRepository.GetUserByID() 호출을 스텁 (stub) 할 수 있습니다.

이렇게하는 것이 가장 좋은 방법입니까? 모든 데이터 액세스가 속성 내에서 숨겨진 대신 리포지토리를 통해 수행되기 때문에 두 번째 구현이 더 깨끗하다고 ​​주장 할 수 있습니다.

답변

0

당신이 필요로하고 CancelOrder 메서드에 대한 인수 형식으로 것을 사용하는 빈약 한 기능을 제공합니다 당신의 자신의 주문 - 비슷하게 인터페이스를 정의합니다

interface Order { 
    public void Status(...); // or property 
    public string UserEmail(): 
} 

그런 다음 해당 인터페이스, 예를 들어,의 위임 구현을 만듭니다 SubsonicOrder, 데이터베이스를 호출합니다. 테스트에 스텁 구현을 사용하십시오. Order 인터페이스에 더 풍부한 모델이 필요할 수도 있다는 것을 알고 있습니다. 이것은 단지 예일뿐입니다.

이메일 서비스와 마찬가지로 (생성자 또는 서비스 위치 지정자를 통한 종속성 삽입을 통해) 동일한 작업을 수행하십시오.

0

당신의 단위 테스트에서 당신의 데이터베이스를 치고 싶지 않은 이유는 무엇입니까? MBUnit을 사용하여 테스트 케이스를 작성하는 경우 단위 테스트에 RollBack 속성을 표시하면 데이터베이스에 대한 모든 변경 사항이 롤백됩니다.

저는 비즈니스 레이어를 대상으로하는 단위 테스트 케이스를 작성하는 것이 좋지만 실제로는 단위 테스트가 응용 프로그램 자체와 가장 비슷하도록 데이터베이스에 ping을 수행합니다.

관련 문제