2009-07-06 4 views
7

저장소 클래스 내의 메서드 만 호출하는 서비스 클래스 내의 메서드에 대한 단위 테스트를 작성해야합니까?

저장소 클래스 (DAL)가 있습니다.

public class MyRepository : IMyRepository 
{ 
    public void Delete(int itemId) 
    { 
     // creates a concrete EF context class 
     // deletes the object by calling context.DeleteObject() 
    } 

    // other methods 
} 
또한 서비스 클래스 (BLL)가 있습니다.

public class MyService 
{ 
    private IMyRepository localRepository; 

    public MyService(IMyRepository instance) 
    { 
     this.localRepository = instance; 
    } 

    public void Delete(int itemId) 
    { 
     instance.Delete(itemId); 
    } 

    // other methods 
} 

MyRepository에 대한 단위 테스트를 작성하면 Entity Framework 컨텍스트를 조롱해야하기 때문에 구현하는 것보다 시간이 더 많이 걸립니다.

하지만 MyService에 대한 단위 테스트를 만드는 것은 저장소에만 호출하기 때문에 난센스가됩니다. 내가 확인할 수있는 것은 그것이 실제로 저장소 삭제 메소드를 호출했는지 확인하는 것입니다.

질문

이러한 쌍의 삭제 방법을 단원 테스트에 제안 하시겠습니까? 양자 모두? 하나? 없음? 그리고 당신은 무엇을 시험하겠습니까?

답변

1

네, 확실히 서비스 계층에 대한 단위 테스트를 작성할 것입니다. 그 이유는 구현이 현재 작동하는지 테스트하는 것이 아니라 앞으로도 계속 작동하는지 테스트하기 때문입니다.

이해해야 할 중요한 개념입니다. 나중에 누군가가 따라 와서 ServiceLayer를 변경하고 단원 테스트가 없으면 기능이 계속 작동하는지 어떻게 확인할 수 있습니까?

나는 DAL에 대한 테스트도 작성할 것이지만, DataTests 또는 다른 어셈블리라는 별도의 어셈블리에 넣을 것입니다. 여기에서의 목적은 어셈블리 전반에 걸쳐 귀하의 관심사를 격리시키는 것입니다. 단위 테스트는 귀하의 DAL과 관련되어서는 안됩니다.

+0

하지만 Service.Delete() 메소드를 테스트 할 경우 Repository.Delete() 메소드를 호출하는지 확인할 수 있습니다. 데이터 조작은 저장소에서 수행되므로 데이터를 확인할 수 없습니다. 기타 (미래) 복잡성은 테스트에 포함되지 않습니다. –

+1

@ 로버트 그것은 완전히 정확하지 않습니다. 모의 IMyRepository 개체를 만들어야합니다. 일단 그렇게하면 서비스 레이어가 delete를 호출 할 때 mock에서 삭제가 호출되는지 확인할 수 있도록 mock을 설정할 수 있습니다. 따라서 Repository.Delete도 테스트하지 않고 Service.Delete 기능을 테스트하고 있습니다. – Joseph

1

예, 둘 다.

IMyRepository mock = ...; 
// create Delete(int) expectation 

MyService service = new MyService(mock); 
service.Delete(100); 

// Verify expectations 

귀하의 삭제 방법은 현재 저장소에서 삭제 방법 만 호출 할 수 있지만 항상 그런 것은 아닙니다. 이것에 대한 단위 테스트가 제대로 작동하는지 확인하고 부분적으로 저장소가 작동하는 방법에 대한 사양을 정의하는 방식으로 수행해야합니다.

또한 리포지토리가 null 인 경우 생성자가 예외를 throw하는지 확인하는 테스트가 있어야합니다. 또한이 메소드에서 수행 할 다른 검증 (예 : 음수가 아닌 ID 또는 0이 아닌 ID)이있을 수 있습니다. 어쩌면 여기에서는 일어나지 않을 수도 있습니다. 예상되는 동작을 검증하는 테스트를 작성하여 스펙에 포함 시키십시오.

그들은 사소한 것처럼 보일 지 모르지만 언젠가는 바뀔 것이라는 보장 만 할뿐입니다. 귀하의 기대와 사양은 검증되지 않을 수도 있습니다.

+0

예제에서 수행 한 모든 작업은 Service.Delete() 테스트입니다. 내 저장소를 조롱하고 실제로 저장소로 호출하는 서비스를 테스트했습니다. –

+0

이전에 언급 한 내용에서 "둘 다"라고 말했지만 서비스 계층을 테스트하는 코드 만 썼습니다. 그러나 예, 귀하의 경우 서비스가 테스트됩니다. –

+0

죄송합니다. 구체적인 저장소를 테스트하기위한 다른 테스트 세트가 있습니다. 이는 타사 라이브러리 및 다른 계층에 종속되어 있기 때문에 더 어려울 수 있습니다. 이러한 테스트는 결국 통합 테스트와 같아 질 수 있습니다. 따라서 둘 다 총 코드 커버리지를 위해 노력하십시오. 하지만이 클래스는 앱을 코딩 할 추상화이므로 무시할 수 있다고 생각하지 않습니다. –

0

서비스 테스트를 만듭니다. 현재은 저장소 삭제 메서드를 호출하는 것입니다. 그러나, 당신은 그것에 대해 신경 쓰지 않아야합니다. 나중에 어떤 일이 발생하고 기능이 훨씬 복잡해지면 어떨까요? 기능이 예상대로 작동하고 있음을 보장하는 단위 테스트 코드를 원하십니까?

서비스를 통해 삭제를 노출하는 경우 효과가있을 것으로 예상됩니다. 단위 테스트를 작성하여 그 효과를 테스트하십시오. 특정 요구 사항에 따라 저장소 삭제에 대한 테스트가 필요하지 않을 수도 있습니다. 특히 해당 기능이 서비스 삭제 기능의 일부로 사용되는 경우 특히 그렇습니다.하지만 실제로는 모든 서비스 수준, 다시 시도하십시오.

+0

하지만 Service.Delete() 메서드를 테스트하면 Repository.Delete() 메서드를 호출하는지 확인할 수 있습니다. 데이터 조작은 저장소에서 수행되므로 데이터를 확인할 수 없습니다. –

+0

Service.Delete()가 Repository.Delete()를 호출하는 것으로 충분합니까? 그럼 그냥 Service.Delete()로 괜찮아. 데이터를 확인해야합니까? 그런 다음 데이터가 수정되는지 확인하기 위해 몇 가지 수준의 조롱이 필요합니다. –

0

또한 TDD로이 코드를 만든 경우 테스트를 거쳤을 것입니다. 실제로 사람들이 서비스를 통해 삭제를 호출 할 수 있는지 여부가 중요하므로 실제로 테스트해야합니다.

0

제 생각에는 두 가지를 모두 테스트해야합니다. 어쩌면 당신은 MyRepository 테스트를 위해보다 쉽게 ​​테스트하고 컨텍스트 클래스를 조롱 할 수있는 별도의 공장에서 생성 EF 컨텍스트 클래스를 수행 할 수 있습니다. 그게 더 쉽고 컨텍스트 호출을 만들기위한 공장을 사용하면 나를 위해 조용한 것 같다.

+0

나는 그물에 구글 수 있기 때문에 Entity Framework 컨텍스트를 조롱하는 것은 고통이다. –

관련 문제