2014-07-26 4 views
3
// acknowledgement: http://stackoverflow.com/a/5022512/1500199 
public class FakeDbSet<T> : IDbSet<T> where T : class 
{ 
    private readonly HashSet<T> data; 
    private readonly IQueryable query; 

    public FakeDbSet() 
    { 
     data = new HashSet<T>(); 
     query = data.AsQueryable(); 
    } 

    public virtual T Find(params object[] keyValues) 
    { 
     throw new NotImplementedException(); 
    } 
} 

Find을 어떻게 구현할 수 있습니까?DbSet을 스텁하는 방법

Find 메서드에서 키 값 비교를 수행하기 위해 기본 키 값을 T으로 결정해야하지만 어떻게해야할지 모르겠다.

+0

가 나는 각 엔티티는 속성을'이 IEntity''와 같은 인터페이스를 구현 할 필요가있을 수 IEntity.Key' 'FakeDbSet '에 대한 일반적인 제약 조건 인'T : IEntity'를 강제 할 것인가? –

+1

스텁 클래스에 dbContext 인스턴스를 추가 할 수 있습니까? –

+0

@YuliamChandra 이해가 안됩니다. –

답변

0

재정의 방법

public class FakePostsDbSet : FakeDbSet<Post> 
{ 
    public override Post Find(params object[] keyValues) 
    { 
     return this.SingleOrDefault(
      post => post.Slug == (string) keyValues.Single()); 
    } 
} 
1

제대로 이해 한 경우 단위 테스트를 위해 DbSet 개체의 Find() 메서드를 스텁링해야합니다.

버전 6 이상이고 Moq 또는 NSubstitute 또는 FakeItEasy와 같은 Mocking Framework를 사용하는 EntityFramework를 사용하는 경우 FakeDbSet과 같은 클래스를 작성하지 않고도 쉽게이 작업을 수행 할 수 있습니다.

이 문서에서는 스텁/조롱 프로세스의 자세한 설명을 제공합니다 http://msdn.microsoft.com/en-us/data/dn314429.aspx

그리고이 문서에서 클래스를 사용하는 예.

[Test] 
    public void Foo_WhenCalled_CallsDb() 
    { 
     //Arrange 
     var fakeDbSet = new Mock<DbSet<Course>>(); 
     fakeDbSet.Setup(dbs => dbs.Find(It.IsAny<object>())).Returns(new Course { CourseID = 125 }); 

     var fakeContext = new Mock<SchoolEntities>(); 
     fakeContext.Setup(c => c.Courses).Returns(fakeDbSet.Object); 


     var foo = new Foo(fakeContext.Object); 

     //Act 
     string result = foo.MyMethod(); 

     //Assert 
     Assert.AreEqual("125", result); 
    } 

다른 버전의 EntityFramework의 경우 "리포지토리"패턴 사용을 고려하면 훌륭한 테스트 기능을 제공합니다. 내 대답이 도움이되기를 바랍니다.

+0

감사합니다. 당신이 이것을 알 수있는 방법은 없지만 이미 가짜 저장소에 대해 작업하고 있기 때문에 이것은 적합하지 않습니다. –

2

이 시도 :

public class FakeDbSet<T> : IDbSet<T> where T : class 
{ 
    private Func<T, object[], bool> _findSelector 
    private readonly HashSet<T> data; 
    private readonly IQueryable query; 

    public FakeDbSet(Func<T, object[], bool> findSelector) 
    { 
     _findSelector = findSelector; 
     data = new HashSet<T>(); 
     query = data.AsQueryable(); 
    } 

    public virtual T Find(params object[] keyValues) 
    { 
     return _data.SingleOrDefault(item => _findSelector(item, keyValues)); 
    } 
} 
+0

감사합니다.이 질문에 대한 답변입니다. 그러나, 나는 이것을 실제로 사용하지 않을 것입니다 - 그것은 총체입니다. 대신 새로운 디자인 전략을 적용 할 것입니다. –

관련 문제