2012-10-30 2 views
11

엔티티 프레임 워크를 사용하고 있으며 EF를 사용하는 데이터 서비스를 단위 테스트하려고합니다. 저장소 및 작업 단위 패턴을 사용하고 있지 않습니다.유닛 테스트 엔티티 프레임 워크 (moq를 사용)

private static Mock<IEFModel> context; 
private static Mock<IDbSet<CountryCode>> idbSet; 

    [ClassInitialize] 
    public static void Initialize(TestContext testContext) 
    { 
     context = new Mock<IEFModel>(); 

     idbSet = new Mock<IDbSet<CountryCode>>(); 

     context.Setup(c => c.CountryCodes).Returns(idbSet.Object); 

    } 

내가 idbSet "로컬"에 대한 오류 "개체 참조가 개체의 인스턴스로 설정되지 않았습니다"널 수 : 나는 상황과 DbSet을 조롱하기 위해 다음과 같은 방법을 시도했다. idbSet을 이와 같이 조롱하는 방법이 있습니까? 감사합니다.

답변

9

나는 이런 식으로 운동했다 th와 같음 이다 : 나는 단지이 줄을 추가

public static Mock<IDbSet<T>> CreateMockSet<T>(IQueryable<T> data) where T : class 
{ 
    var mockSet = new Mock<IDbSet<T>>(); 
    mockSet.As<IQueryable<T>>().Setup(m => m.Provider).Returns(data.Provider); 
    mockSet.As<IQueryable<T>>().Setup(m => m.Expression).Returns(data.Expression); 
    mockSet.As<IQueryable<T>>().Setup(m => m.ElementType).Returns(data.ElementType); 
    mockSet.As<IQueryable<T>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator()); 
    return mockSet; 
} 

: :이처럼 내 모의 세트를 생성하는 방법을 사용하고 있었다

[TestClass] 
public class CountryCodeServiceTest 
{ 
    #region Static Fields 

    /// <summary>The context.</summary> 
    private static IEFModel context; 

    #endregion 

    #region Public Methods and Operators 

    /// <summary>The initialize.</summary> 
    /// <param name="testContext">The test context.</param> 
    [ClassInitialize] 
    public static void Initialize(TestContext testContext) 
    { 
     context = new EFModelMock(); 
    } 

    /// <summary>The country code service get country codes returns correct data.</summary> 
    [TestMethod] 
    public void CountryCodeServiceGetCountryCodesReturnsCorrectData() 
    { 
     // Arrange 
     var target = new CountryCodeService(context); 
     var countryName = "Australia"; 
     var expected = context.CountryCodes.ToList(); 

     // Act 
     var actual = target.GetCountryCodes(); 

     // Assert 
     Assert.IsNotNull(actual); 
     Assert.AreEqual(actual.FirstOrDefault(a => a.CountryName == countryName).PhoneCode, expected.FirstOrDefault(a => a.CountryName == countryName).TelephoneCode); 
    } 
+1

당신은 ...이 질문/답변에 대해 더 많은 평판을 필요로합니다. 나는 많은 사람들이이 문제를 안고 있음을 알았다. 나는이 길로 갈 필요가 없길 희망했으나 이미 무거운 짐을 지었다. :) – vbullinger

+0

미안하지만 ... 어떤 인터페이스인가? IEFModelMock? – GustavoAdolfo

2

idbSet 모의의 Local 속성을 설정해야합니다. 예를 들어


는 : 만든 두 클래스의 이름 DbSetMock :

public class DbSetMock<T> : IDbSet<T> 
    where T : class 
{ 
    #region Fields 

    /// <summary>The _container.</summary> 
    private readonly IList<T> _container = new List<T>(); 

    #endregion 

    #region Public Properties 

    /// <summary>Gets the element type.</summary> 
    public Type ElementType 
    { 
     get 
     { 
      return typeof(T); 
     } 
    } 

    /// <summary>Gets the expression.</summary> 
    public Expression Expression 
    { 
     get 
     { 
      return this._container.AsQueryable().Expression; 
     } 
    } 

    /// <summary>Gets the local.</summary> 
    public ObservableCollection<T> Local 
    { 
     get 
     { 
      return new ObservableCollection<T>(this._container); 
     } 
    } 

    /// <summary>Gets the provider.</summary> 
    public IQueryProvider Provider 
    { 
     get 
     { 
      return this._container.AsQueryable().Provider; 
     } 
    } 

    #endregion 

    #region Public Methods and Operators 

    /// <summary>The add.</summary> 
    /// <param name="entity">The entity.</param> 
    /// <returns>The <see cref="T"/>.</returns> 
    public T Add(T entity) 
    { 
     this._container.Add(entity); 
     return entity; 
    } 

    /// <summary>The attach.</summary> 
    /// <param name="entity">The entity.</param> 
    /// <returns>The <see cref="T"/>.</returns> 
    public T Attach(T entity) 
    { 
     this._container.Add(entity); 
     return entity; 
    } 

    /// <summary>The create.</summary> 
    /// <typeparam name="TDerivedEntity"></typeparam> 
    /// <returns>The <see cref="TDerivedEntity"/>.</returns> 
    /// <exception cref="NotImplementedException"></exception> 
    public TDerivedEntity Create<TDerivedEntity>() where TDerivedEntity : class, T 
    { 
     throw new NotImplementedException(); 
    } 

    /// <summary>The create.</summary> 
    /// <returns>The <see cref="T"/>.</returns> 
    /// <exception cref="NotImplementedException"></exception> 
    public T Create() 
    { 
     throw new NotImplementedException(); 
    } 

    /// <summary>The find.</summary> 
    /// <param name="keyValues">The key values.</param> 
    /// <returns>The <see cref="T"/>.</returns> 
    /// <exception cref="NotImplementedException"></exception> 
    public T Find(params object[] keyValues) 
    { 
     throw new NotImplementedException(); 
    } 

    /// <summary>The get enumerator.</summary> 
    /// <returns>The <see cref="IEnumerator"/>.</returns> 
    public IEnumerator<T> GetEnumerator() 
    { 
     return this._container.GetEnumerator(); 
    } 

    /// <summary>The remove.</summary> 
    /// <param name="entity">The entity.</param> 
    /// <returns>The <see cref="T"/>.</returns> 
    public T Remove(T entity) 
    { 
     this._container.Remove(entity); 
     return entity; 
    } 

    #endregion 

    #region Explicit Interface Methods 

    /// <summary>The get enumerator.</summary> 
    /// <returns>The <see cref="IEnumerator"/>.</returns> 
    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return this._container.GetEnumerator(); 
    } 

    #endregion 
} 

및 EFModelMock : 그런 다음 테스트

public class EFModelMock : IEFModel 
{ 
    #region Fields 

    /// <summary>The country codes.</summary> 
    private IDbSet<CountryCode> countryCodes; 

    #endregion 

    #region Public Properties 

    /// <summary>Gets the country codes.</summary> 
    public IDbSet<CountryCode> CountryCodes 
    { 
     get 
     { 
      this.CreateCountryCodes(); 
      return this.countryCodes; 
     } 
    } 


    #endregion 

    #region Public Methods and Operators 

    /// <summary>The commit.</summary> 
    /// <exception cref="NotImplementedException"></exception> 
    public void Commit() 
    { 
     throw new NotImplementedException(); 
    } 

    /// <summary>The set.</summary> 
    /// <typeparam name="T"></typeparam> 
    /// <returns>The <see cref="IDbSet"/>.</returns> 
    /// <exception cref="NotImplementedException"></exception> 
    public IDbSet<T> Set<T>() where T : class 
    { 
     throw new NotImplementedException(); 
    } 

    #endregion 

    #region Methods 

    /// <summary>The create country codes.</summary> 
    private void CreateCountryCodes() 
    { 
     if (this.countryCodes == null) 
     { 
      this.countryCodes = new DbSetMock<CountryCode>(); 
      this.countryCodes.Add(
       new CountryCode { CountryName = "Australia", DisplayLevel = 2,  TelephoneCode = "61" }); 

     } 
    } 

    #endregion 
} 

idbSet = new Mock<IDbSet<CountryCode>>(); 

var col = new ObservableCollection<CountryCode>(); 
idbSet.SetupGet(x => x.Local).Returns(col); 
+1

답변을 주셔서 감사합니다.하지만 작동하지 않아 결국 IDBSet과 IEFModel을 수동으로 조롱했습니다. – Khash

0

반환 문 앞에

mockSet.Setup(x => x.Local).Returns(new ObservableCollection<T>()); 

을하고 해결 내 문제. 내 쿼리의

많은는 다음과 같다 : 그것은 null 참조 예외가 발생하지 않도록

var myset = context.EntitySetName.Local.SingleOrDefault(x=>x.something==something) 
      ?? 
      context.SingleOrDefault(x=>x.something==something); 

그래서 난 그냥 null이 될 수 없습니다 로컬 필요합니다.

관련 문제