2011-09-02 4 views
2

나는 데이터베이스 액세스에 대한 엔티티 프레임 워크 4.1을 사용하고 있습니다 및 단위 테스트에 다음 코드를 좋아하는 것 : 나는 그러나 내가 끼 었어 데이터베이스 종속성을 몰 몰을 사용하고어떻게 Moles를 사용하여 DbContext를 두드려 EntityFramework 4.1에서 데이터베이스를 쿼리합니까?

// Get all the entities including children 
using (MyContext context = new MyContext()) 
{ 
    return context.EmployeeProfiles.Include("EmployeeProperties").ToList(); 
} 

. 엔티티 프레임 워크에서 어떤 점을 시작해야할까요?

다음은이 example이지만 LINQ-To-SQL 용입니다.

또한 데이터베이스 호출이 이루어지기 전에 어떤 기능을 인터셉트할지 알아 내기 위해 Entity Framework를 디버깅/추적하는 것을 고려 중이었습니다. 그러나 Entity Framework 4.1에서 사용할 수있는 소스 코드가없는 것으로 보입니다. discussion을 참조하십시오.

누구든지 나를 안내 할 수 있습니까? 나는 DbContext에서 탈주해야하므로 EmployeeProfiles 목록을 다시 얻을 수 있습니까?

+0

재미있는 질문입니다.이 코드를 단위 테스트하는 것이 필요한지 알고 싶습니다. 이것은 저장소의 일부이고 기본적으로'GetFullEmployeeProfiles'와 같은 메소드의 구현이라고 가정하고, 실제로 'EmployeeProfiles'와 'EmployeeProperties'가 다시 채워지는 것을 확인하는 단위 테스트를 작성하려고합니다. – Rudi

+0

예 코드는 저장소의 일부이며 해당 영역을 단위 테스트합니다. 그러나 단위 테스트를 수행하여 Entity Framework를 조금 더 멀리 두드려보고 내 예상 엔티티를 되 돌리려했습니다. DBContext를 조롱하는 데 가장 가까운 정보는 두더지를 사용하지 않습니다. http://romiller.com/2010/09/07/ef-ctp4-tips-tricks-testing-with-fake-dbcontext/ – walleye

답변

0

저는 리포지토리 패턴을 통해 EF에 대한 종속성을 제거하는 대신 EF의 특정 동작을 조롱하려고합니다. 나는 그 일을 시도하는 데있어 요점을 볼 수 없으며 매우 어려울 것입니다. EF는 조롱받을 의도가 없습니다. 당신이 EmployeeProfiles가 반환 방법에 대한 저장소 종속성을 제거한

public interface IRepository 
{ 
     IEnumerable<EmployeeProfiles> EmployeeProfiles { get; } 
} 

public class Repository 
{ 
    public IEnumerable<EmployeeProfiles> EmployeeProfiles 
    { 
     get 
     { 
      // Get all the entities including children  
      using (MyContext context = new MyContext())  
      { 
       return context.EmployeeProfiles.Include("EmployeeProperties").ToList();  
      } 
     } 
    } 
} 

이 방법 :

저장소 (repository)는 아마도이 같은 것입니다. 지금 당신은 당신의 마음의 콘텐츠에 멀리 조롱 수 있습니다 (아직 두더지를 사용하지 않은), 그러나 MOQ, 당신은 같은 것을 할 것입니다 : 당신이 방법을 세우면

public void TestEmptyList() 
{ 
    var mock = new Mock<IRepository>(); 
    var expected = new List<EmployeeProfiles>(); 
    mock.SetupGet(ep => ep.EmployeeProfiles).Returns(expected); 

    var actual = mock.Object.EmployeeProfiles; 

    Assert.AreEqual(expected, actual); 
} 

그래서,/속성을 사용하면 멀리 추상적 원하는을 데이터베이스에서 저장소 인터페이스로 이동하면 테스트 할 값을 반환 할 수 있습니다.

아마도 어쨌든이 작업을 수행하고 있을지 모르겠습니다. 왜 당신이 단위 테스트 EF를 원할지 모르겠지만, 무엇을 얻고 싶습니까? 그것은 엄청나게 어려울 것이며 조롱 당하지 않을 것입니다 (아주 소수의 인터페이스/가상). 반환하는 데이터 조롱은 실제로 당신이 정말로 흥미로워하는 모든 것이 위와 같이 수행됩니다.

+0

유일한 것은 EF를 조롱 한 이유는 저장소와 EF 간의 코드 커버리지를 증가시키는 것이 었습니다. 나는 두더지를 사용하고 EF에 연결하는 것이 간단한 작업이라고 생각했습니다. 현재 단위 테스트로 저장소 계층을 단위 테스트합니다. 도움 주셔서 감사합니다. – walleye

+0

EF *를 조롱하는 것은 어렵지만, 진정한 단위 테스트를 얻는 유일한 방법입니다. 저장소를 조롱하는 것은 믿을 수 없을 정도로 쉽지만 사실 Linq를 개체가 아닌 Linq를 사용하는 시뮬레이션 작업에 녹색 불빛을 제공합니다. 따라서 우리 앱이 실제로 사용하고있는 것을 테스트하는 것이 아닙니다. 현재 T4 템플릿을 수정하여 DbContext가 인터페이스를 구현하도록 만들어서 조롱합니다. 변경 추적과 같은 고급 작업을 처리하는 방법을 아직 모릅니다. 실제로 데이터베이스를 사용하는 통합 테스트로 넘어갈 필요가 있습니다. –

+0

그렇습니다. 대부분의 사람들이 통합 테스트가 필요하다고 주장 할 것이라고 생각합니다. 분명히 L2O와 L2E의 차이는 상당히 크지 만, 단위 테스트에서는 이것이 중요하지는 않지만 동시에 그 차이를 인식해야합니다. 아마도 문제는 객체 - 관계형 매핑 그 자체의 개념입니다. – nicodemus13

0

이것은 완전히 가능하며 내 의견으로는 유효합니다. 예, 저장소 패턴을 사용하고 저장소를 조롱 할 수 있으며, 종종 그 정도면 충분합니다.

그러나, 나는 조롱 EF 본적이 개 인수 :

  1. EF는 필요하지 않습니다 주위에 다른 저장소를 작성, 이미 실제 데이터베이스에 대한 추상화/저장소입니다.
  2. EF를 통해 작성하는 저장소는 코드입니다. 그러므로 조만간 적용 할 논리를 추가 할 것이므로 조만간 테스트해야합니다.

이 시점에서 약간의 거룩한 전쟁이지만, 현재 진행중인 작업을 지원하는 논쟁이 있습니다.

따라서 Moles에서이를 수행하려면 두 가지 작업을 수행해야합니다. 먼저 모든 테이블의 반환 형식이 DbSet<> 대신 IDbSet<>이되도록 DbContext를 만드는 템플릿을 변경합니다.

그런 다음 테스트 프로젝트에서 IDbSet에 대한 테스트 클래스 구현을 추가하십시오. 나는 잘 작동하려면 this one을 찾았습니다.

이제, 테스트, 당신은 다음과 같은 작업을 수행 할 수

List<EmployeeProfile> testProfiles = /*your test data here*/; 
MMyContext.AllInstances.EmployeeProfilesGet = (instance) => 
{ 
    return new InMemoryDbSet<EmployeeProfile>(testProfiles); 
}; 


// Get all the entities including children 
using (MyContext context = new MyContext()) 
{ 
    return context.EmployeeProfiles.Include("EmployeeProperties").ToList(); 
} 

그것은 빠르고 간단합니다, 당신은 바로 당신의 코드를 테스트 할 수 있습니다 매우 그것은 당신의 컨트롤을 벗어나 가리 킵니다.