使用最小起订量进行单元测试实体框架 [英] Unit test Entity Framework using moq

查看:77
本文介绍了使用最小起订量进行单元测试实体框架的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用实体框架,并试图对使用EF的数据服务进行单元测试. 我没有使用存储库和工作单元模式. 我尝试了以下方法来模拟上下文和DbSet:

I'm using entity framework and trying to unit test my data services which are using EF. I'm not using repository and unit of work patterns. I tried the following approach to mock the context and DbSet:

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本地",我得到空的对象引用未设置为对象的实例"错误. 有什么办法可以像这样模拟idbSet吗? 谢谢

I get null "Object reference not set to an instance of an object" error for idbSet "Local". Is there any way to mock idbSet like this? Thanks

推荐答案

我这样解决: 创建了两个名为DbSetMock的类:

I worked it out like this: Created two classes named 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:

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

然后像这样测试:

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

这篇关于使用最小起订量进行单元测试实体框架的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆