2016-08-03 3 views
0

EF 6을 사용하여 DbContext를 조롱하는 명확한 작동 예제를 보여주는 여러 가지 예제를 발견했습니다. 그러나 그 중 아무 것도 나를 위해 작동하지 않는 것으로 보입니다.Entity Framework 6.1의 DbContext 조롱

mock을 설정하는 단위 테스트 코드입니다.

var mockData = new List<User> { new User { Email = "[email protected]", Id = 1 } }.AsQueryable(); 

var mockSet = new Mock<DbSet<User>>(); 
    mockSet.As<IQueryable<User>>().Setup(m => m.Provider).Returns(mockData.Provider); 
    mockSet.As<IQueryable<User>>().Setup(m => m.Expression).Returns(mockData.Expression); 
    mockSet.As<IQueryable<User>>().Setup(m => m.ElementType).Returns(mockData.ElementType); 
    mockSet.As<IQueryable<User>>().Setup(m => m.GetEnumerator()).Returns(mockData.GetEnumerator()); 

    var mockContext = new Mock<MyDbContext>(); 
    mockContext.Setup(c => c.Users).Returns(mockSet.Object); 

그런 다음 테스트 할 서비스를 호출하십시오.

var service = new UsersService(mockContext.Object); 

var user = service.GetById(1); 

기본 DbSet이 항상 Null이므로 NullReferenceException을 발생시킵니다. 코드는 다음을 수행합니다.

In BaseClass;

public IEnumerable<T> GetAll() 
{ 
    return _dbSet.AsEnumerable(); 
} 

하위 클래스에서;

public User GetById(int id) 
     { 
      return GetAll().FirstOrDefault(x => x.Id == id); 
     } 

관련이있는 것으로 나타 SO에 대한 다른 질문이 있지만, 그들은 EF를 참조 6.

적용되지 않음을 유의하시기 바랍니다이 있다는 MSDN 문서 인 변형과 같은 코드 컴파일해라.

https://msdn.microsoft.com/en-us/data/dn314429.aspx

편집 : UserService (그 용도 제네릭/인터페이스)의 복잡성을 감소시키기는

코드는 단순히 현재이고;

public User GetById(int id) 
     { 
      return _dbContext.Set<User>().FirstOrDefault(x => x.Id == id); 
     } 

var dbSet = _dbContext.Set<User>(); 
     return dbSet.FirstOrDefault(x => x.Id == id); 

분명히 dbSet이 null임을 알 수 있습니다. wablab의 제안으로 당

편집 2

, 모의 .SET 문제가 해결 것으로 보인다.

DbSet에 대한 일반 방법은 Vladyslav Kushnir에게도 기증합니다.

필요로하는 사람을위한 작업 코드. 여기

private static Mock<DbSet<T>> GetDbSetMock<T>(IEnumerable<T> items = null) where T : class 
     { 
      if (items == null) 
      { 
       items = new T[0]; 
      } 

      var dbSetMock = new Mock<DbSet<T>>(); 
      var q = dbSetMock.As<IQueryable<T>>(); 

      q.Setup(x => x.GetEnumerator()).Returns(items.GetEnumerator); 

      return dbSetMock; 
     } 



var mockContext = new Mock<Model1>(); 

var users = new List<User> { new User { Email = "[email protected]", Id = 1 } }; 

mockContext.Setup(x => x.Set<User>()).Returns(GetDbSetMock(users).Object); 

var service = new UsersService(mockContext.Object); 

var user = service.GetById(1); 
+0

'UserService' 생성자가'_dbSet' 필드에 전달 된 매개 변수의'Users' 속성을 할당하고 있음을 확인 했습니까? – wablab

+0

그게 무슨 뜻인지 모르겠네요. – ChrisBint

+0

'GetById' 메소드 또는'GetAll' 메소드에서'NullReferenceException'이 던져 집니까? 즉,'_dbSet'은 null이거나'_dbSet.AsEnumerable()'null의 결과인가? (아니면 뭔가 다른 것입니까?) – wablab

답변

3

나는 당신이 당신의 모의를 반환하는 Set<User>() 방법에 설정을 만들 필요가 있다고 생각합니다.

+0

완벽하게 작동했습니다. 감사 – ChrisBint

0
private Mock<DbSet<T>> GetDbSetMock<T>(IEnumerable<T> items = null) where T : class 
    { 
     if (items == null) 
     { 
      items = new T[0]; 
     } 

     var dbSetMock = new Mock<DbSet<T>>(); 
     var q = dbSetMock.As<IQueryable<T>>(); 

     q.Setup(x => x.GetEnumerator()).Returns(items.GetEnumerator); 

     return dbSetMock; 
    } 

내가 DbContext의 DbSet을 조롱에 대한 사용하고 내 꽤 잘 작동하는 일반적인 방법입니다. 이 방법의 실제로 사용 호출은 다음과 같습니다

var contextMock = new Mock<MyContext>(); 
contextMock.Setup(x => x.MyDbEntities).Returns(GetDbSetMock<MyDbEntity>().Object); 
+0

이상하게도 내 컴퓨터에서 작동하지 않는 dbset은 여전히이 코드를 사용하여 null입니다. 감사합니다. – ChrisBint

+0

또한 내 컨텍스트 내에서'DbSet' 대신'IDbSet'을 사용하고 있습니다. 아마도 도움이 될 것입니다. –

+0

아마도이 코드를 사용할 수 없습니다. 왜냐하면'Set '을 통해 데이터에 액세스하려고 시도하는 동안 DbContext의 특정 속성을 조롱하고 있기 때문입니다.이 메서드를 추가로 조롱 해보십시오. –

관련 문제