2012-10-30 3 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のような次のとおりです。

[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プロパティを設定する必要があります。例えば


は: 作成した2つのクラスの名前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

私はこのような私のモックセットを作成する方法を使用していた:returnステートメントの前に

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

、それは解決:

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; 
} 

私は単にこの行を追加しました私の問題。

私の質問の多くは

は、次のようになります。

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

だから私はちょうどそれがnull参照の例外をスローしないようにnullでないように現地を必要としています。

関連する問題