2011-08-18 4 views
1

아래 메서드 "GetByEmail"에 대한 테스트 사례를 만들고 싶습니다. 위의 테스트 케이스 방법에관련된 엔터티를 포함하는 방법

[Fact] 
private void GetByEmail_PassedEmailAddress_RelatedUser() 
{ 
    //Created fake context 
    var fakeContext = Isolate.Fake.Instance<Entities>(); 

    //Created fake Repository and passed fakeContext to it 
    var fakeRepository = Isolate.Fake.Instance<Repository>(Members.CallOriginal, ConstructorWillBe.Called, fakeContext); 

    //Created fake in memory collection of User 
    var fakeUsers = GetUsers(); 

    Isolate.WhenCalled(() => fakeContext.Context.CreateObjectSet<User>()) 
     .WillReturnCollectionValuesOf(fakeUsers); 

    var User = Isolate.Invoke.Method(fakeRepository, "GetByEmail", "[email protected]", true, true); 

    Assert.True(User != null); 
} 

내가 성공적으로 전달 된 이메일로 사용자를 얻을 수 있지만 수없는이 연결된 사용자의 다른 개체를 포함하는 -

public User GetByEmail(string email, bool includeUserRoles = false, bool includeUserType = false) 
{ 
    Expression<Func<User>> whereClause = u => u.Email == email; 

    return GetQuery(whereClause, includeUserRoles, includeUserType) .FirstOrDefault(); 
} 

private IQueryable<User> GetQuery(Expression<Func<User>> whereClause, 
            bool includeUserRoles = false, bool includeUserType = false) 
{ 
    IQueryable<User> query = base.GetQuery(whereClause); 

    if (includeUserRoles) 
    query = query.Include(u => u.UserRoles); 

    if (includeUserType) 
    query = query.Include(u => u.UserType); 

    return query; 
} 

protected IQueryable<T> GetQuery<T>(Expression<Func<T>> predicate) where T : EntityBase 
{ 
    return predicate != null ? 
      CreateObjectSet<T>().Where(predicate) : 
      CreateObjectSet<T>(); 
} 

protected IObjectSet<T> CreateObjectSet<T>() where T : EntityBase 
{ 
    return _context.CreateObjectSet<T>(); 
} 

public static IQueryable<T> Include<T>(this IQueryable<T> source, Expression<Func<T>> property) 
{ 
    var objectQuery = source as ObjectQuery<T>; 

    if (objectQuery != null) 
    { 
     var propertyPath = GetPropertyPath(property); 
     return objectQuery.Include(propertyPath); 
    } 

    return source; 
} 

다음은 내 테스트 케이스의 방법이다.

관련 사용자가있는 다른 엔티티를 어떻게 포함시킬 수 있습니까?

답변

2

Include은 누출 추상화입니다. 이는 EF 및 linq-to-entities에서만 작동하며 linq-to-objects와 함께 성공적으로 사용할 수 없습니다. 단위 테스트에 채워진 관계가 필요하므로 GetUsers 메소드는 해당 데이터를 준비해야합니다. 그것은 조롱/위조의 한 부분입니다 - 당신은 조롱 된 방법의 내부 구현에 대해 생각하지 않습니다. 당신은 반환되어야하는 것을 단순히 반환합니다.

btw. 시험의 요점은 무엇입니까? 모의 테스트를하는 것처럼 보입니다 - 틀 렸습니다. Mock은 올바른 데이터를 제공하며 조롱 된 구성 요소에 종속 된 다른 기능을 테스트하는 데에만 필요합니다.

+0

사용자로 IQueryable을 반환합니다. Iqueryable 대신 다른 것을 돌려 주어야합니까? 민간 된 IQueryable GetUsers() { var에 목록 = 새로운 목록 { \t \t 새 사용자() {사용자 ID = 1, 이름은 = "ABC"성이 = "XYZ", USEREMAIL = " 새 사용자() {UserID = 3, 새 사용자()}, 새 사용자() , FirstName = "pqr", 성 = "stu", UserEmail = "pqr @ stu"}, }}; return list.AsQueryable(); } – Yogesh

+0

IQueryable을 반환하면 리포지토리를 놀랍지 않게 만들고 종속 코드를 테스트 할 수있는 단위를 거의 만들지 않습니다. 이 문제에 대해 여러 게시물을 썼습니다. 그것을 확인 [여기] (http://stackoverflow.com/questions/6766478/unit-testing-dbcontext) 또는 [여기] (http://stackoverflow.com/questions/6904139/fake-dbcontext-of-entity-framework -4-1 테스트). 'IQueryable'은 EF로 응용 프로그램을 개발하는 방법이지만 조롱 된'IQueryable'에 대한 단위 테스트가 실제 응용 프로그램을 테스트 할 수 있도록하는 것은 현재 불가능합니다. 필자의 평소 권장 사항은'IQueryable'을 숨기거나 실제 DB와의 통합 테스트를 사용하는 것입니다. –

관련 문제