UnitTest EF Core InMemoryDatabase - 基本CRUD操作中的行ID不匹配

时间:2018-01-30 13:19:23

标签: c# entity-framework asp.net-core

我有一个Visual Studio 2017 .NET Core 2.0项目,EF Core作为ORM用于与数据库通信。 我试图使用XUnit对创建的DBContext进行简单测试。

但是遇到了这个问题,只有在选择每次都会发生的RunAll时才会发生。但是,如果我进行单个测试或将所有测试添加到播放列表并运行所有测试并不会重现并且测试通过。

现在问题出在下面的TestGet()方法中,当我执行service.Create(dbcontext.add)时,它每次返回ID为1。 但是,当我使用service.Get(id)调用ID 1的数据时,它返回null,如果我执行service.GetAll(),则返回实际ID为2的单个项目。

即使inMemoryDB实际使用ID 2创建了它,服务如何返回ID为1,并且只有在执行RunAll测试时才会发生。

所需的所有代码应在下面。请注意,它已经过多个文件的编辑和粘贴。

    public class TestClass
    {
        [Fact]
        public async void TestGet()
        {
            using (var context = new CoreContext(CoreInMemoryDbContextOptions.Get()))
            {
                var _testService = new TestService(context);
                var newTest = new Test 
                {
                    Name = "Test",
                };
                var itemId = await _testService.Create(newTest); //returns ID 1

                var items = await _testService.GetAll(); //returns single item with ID 2
                var item = await _testService.Get(itemId); //NullException
                Assert.Equal("Test", item.Name);
            }
        }
    }

    public class TestService
    {
        private CoreContext _context;
        public TestService(CoreContext context)
        {
            _context = context;
        }

        public async Task<Data.Test> Get(int id)
        {
            return await _context.Tests.Where(x => x.TestId == id).SingleOrDefaultAsync();
        }

        public async Task<int> Create(Test component)
        {
            component.TestId = 0;
            _context.Tests.Add(component);
            return await _context.SaveChangesAsync();
        }
    }


    public class CoreInMemoryDbContextOptions
    {
        public static DbContextOptions<CoreContext> Get()
        {
            DbContextOptions<CoreContext> options;
            var builder = new DbContextOptionsBuilder<CoreContext>();
            builder.UseInMemoryDatabase(databaseName: Guid.NewGuid().ToString());
            options = builder.Options;

            CoreContext coreContext = new CoreContext(options);
            coreContext.Database.EnsureDeleted();
            coreContext.Database.EnsureCreated();
            return options;
        }
    }

1 个答案:

答案 0 :(得分:3)

您对SaveChangesAsync的返回值的理解存在缺陷。您在测试中假设它返回id。那是错的。它返回成功操作的计数,因为您正在保存单个实体,它是1.它始终为1.如果您想要id,则需要在保存后从PK属性中获取它。 EF将使用创建的id回填该属性,但它不会直接返回id。