0

我有一个基础对象,其中包含一个 Version 属性,标记为 ConcurrencyCheck

public class EntityBase : IEntity, IConcurrencyEnabled
{
    public int Id { get; set; }
    [ConcurrencyCheck] 
    [Timestamp]
    public byte[] Version { get; set; }
}

这可行,但是,我想编写一个测试以确保它不会被破坏。不幸的是,我似乎无法弄清楚如何编写不依赖于物理数据库的测试!

以及有效的相关测试代码,但使用数据库......

    protected override void Arrange()
    {
        const string asUser = "ConcurrencyTest1"; // used to anchor and lookup this test record in the db

        Context1 = new MyDbContext();
        Context2 = new MyDbContext();
        Repository1 = new Repository<FooBar>(Context1);
        Repository2 = new Repository<FooBar>(Context2);
        UnitOfWork1 = new UnitOfWork(Context1);
        UnitOfWork2 = new UnitOfWork(Context2);

        Sut = Repository1.Find(x => x.CreatedBy.Equals(asUser)).FirstOrDefault();

        if (Sut == null)
        {
            Sut = new FooBar
                {
                    Name = "Concurrency Test"
                };

            Repository1.Insert(Sut);
            UnitOfWork1.SaveChanges(asUser);
        }

        ItemId = Sut.Id;
    }

    protected override void Act()
    {
        _action = () =>
            {
                var item1 = Repository1.FindById(ItemId);
                var item2 = Repository2.FindById(ItemId);

                item1.Name = string.Format("Changed @ {0}", DateTime.Now);
                UnitOfWork1.SaveChanges("test1");

                item2.Name = string.Format("Conflicting Change @ {0}", DateTime.Now);
                UnitOfWork2.SaveChanges("test2"); //Should throw DbUpdateConcurrencyException
            };
    }

    [TestMethod]
    [ExpectedException(typeof(DbUpdateConcurrencyException))]
    public void Assert()
    {
        _action();
    }

如何删除数据库要求???

4

2 回答 2

0

我建议将您的 MyDbContext 提取到一个 interfaceIMyDbContext中,然后创建一个 TestDbContext 类,该类也将按照您在那里的方式实现 SaveChanges,除了返回一个随机值(如 1)而不是实际保存到数据库中。

那时,您需要做的就是测试,事实上,所有实体的版本号都增加了。

或者您也可以执行此处此处找到的示例。

编辑:我实际上只是在这篇博文中找到了一个使用 TimeStamp 进行并发检查的直接示例。

于 2013-01-03T14:50:27.947 回答
0

我认为你不应该试图模拟这种行为来启用“纯”单元测试。有两个原因:

  • 它需要大量模拟数据库行为的代码:以具有版本值的方式实现对象,缓存原始对象(以模拟存储),在更新时修改版本值,将版本值与原始值进行比较,当版本不同时抛出异常,甚至更多。所有这些代码都可能存在错误,更糟糕的是,可能与实际情况略有不同。

  • 您将陷入循环推理:您专门为单元测试编写代码,然后……您编写单元测试来测试此代码。绿色测试表明一切正常,但未涵盖应用程序代码的基本部分。

这只是 linq 到难以(不可能)模拟的实体的众多方面之一。我在这里编制了这些差异的列表。

于 2013-01-04T18:11:31.977 回答