【问题标题】:Moq testing repository codeMoq 测试存储库代码
【发布时间】:2014-08-12 03:15:05
【问题描述】:

我很困惑是否应该在存储库上进行 TDD。我知道它没有做任何主要的运营/业务功能。但是,许多人也在对 Repository 进行测试。

我可以理解,这实际上是一个集成测试,数据将直接命中数据库。

我的 GenericRepository 有一个 Insert 方法:

public virtual bool Insert(TEntity entity)
        {
            var validationResult = this.context.Entry(entity).GetValidationResult();

            if (validationResult.IsValid)
            {
                this.databaseSet.Add(entity);
                return true;
            }
            else
            {
                var errors = new List<DbEntityValidationResult>();
                errors.Add(validationResult);
                throw new DbEntityValidationException(string.Empty, errors);
            }
        }

现在我想用最小起订量来测试这个方法。 TestInitializer 如下所示:

[TestInitialize]
        public void Initialize()
        {
            // Arrange.
            this.MockData = new List<Document> 
            { 
                new Document { },
            }.AsQueryable();

            this.MockSet = new Mock<DbSet<Document>>();
            this.MockSet.As<IQueryable<Document>>().Setup(m => m.Provider).Returns(this.MockData.Provider);
            this.MockSet.As<IQueryable<Document>>().Setup(m => m.Expression).Returns(this.MockData.Expression);
            this.MockSet.As<IQueryable<Document>>().Setup(m => m.ElementType).Returns(this.MockData.ElementType);
            this.MockSet.As<IQueryable<Document>>().Setup(m => m.GetEnumerator()).Returns(this.MockData.GetEnumerator());

            var entity = new Mock<DbEntityEntry<Document>>();
            this.MockContext = new Mock<IDbContext>();

            this.MockContext.Setup(m => m.Set<Document>()).Returns(this.MockSet.Object);
            this.Repository = new DocumentRepository(this.MockContext.Object);
        }

我的测试插入如下:

[TestMethod]
public void InsertDocument()
{
    var document = new Document()
    {
        Binary = new byte[] { 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 },
    };

    Assert.IsTrue(this.Repository.Insert(document));

    var exceptionMessage = string.Empty;
    Assert.IsTrue(this.Repository.Save(out exceptionMessage));
}

为什么要对存储库进行测试?

我想要的原因是因为它具有我可以检查模型的验证功能。

问题出在哪里?

我无法通过 Insert 函数的 this.context.Entry(entity),因为它返回 null。

即使我尝试使用

设置模拟

var dbEntity = this.MockContext.Object.Entry(document);

this.MockContext.Setup(m => m.Entry(It.IsAny())).Returns(dbEntity);

它返回 NULL 异常。

请告知,如果它和离开呼吸测试一样好。

【问题讨论】:

  • 您不得不对存储库进行单元测试,因为它包含逻辑。但是该逻辑不是您的应用程序域的一部分,它在 DAL 中。我不相信您会通过知道在受控情况下(例如在您的单元测试中)Insert 方法将返回真或假来获得很多。而是将测试重点放在业务和 UI 逻辑上,因为这会为单元测试带来更多价值,因为它们会立即转化为业务需求。

标签: tdd moq repository-pattern asp.net-web-api2


【解决方案1】:

没有必要单独测试存储库(使用模拟数据库网关),因为存储库只是返回 AR(聚合根),AR 应该使用工厂创建,因此如果需要,最好只测试工厂。

测试存储库是否是一个集成测试是有意义的,因此使用实际工作的数据库(快速运行的简单存储库实现,即 sqlite)。

记住测试金字塔

【讨论】:

    猜你喜欢
    • 2013-11-03
    • 2019-08-10
    • 1970-01-01
    • 1970-01-01
    • 2020-01-11
    • 1970-01-01
    • 2018-08-17
    • 2014-12-04
    • 1970-01-01
    相关资源
    最近更新 更多