首页 > 解决方案 > 单元测试无法跟踪实体类型的实例,因为已经在跟踪另一个具有与 {'Id'} 键值相同的实例

问题描述

我正在编写一个 webAPI unittest,它对类中的每个方法都有几个测试调用。我正在使用 UseInMemoryDatabase 创建数据库并加载测试数据。

我在每种测试方法之间收到以下错误

无法跟踪实体类型“AppSettings”的实例,因为已经在跟踪具有相同键值 {'myId'} 的另一个实例。附加现有实体时,请确保仅附加一个具有给定键值的实体实例

我添加了 context.Database.EnsureDeleted(); 并且删除了 Get 方法的错误,但它仍然在删除和更新单元测试中抛出错误。

当我一次运行所有测试方法时,我不知道如何删除此错误以进行删除和更新。

任何帮助表示赞赏。

        private MyDBContext context;

        [TestInitialize]
        public void SetUp()
            {
            var options = new DbContextOptionsBuilder<MyDBContext>()
                .UseInMemoryDatabase(databaseName: "MyDB")
                .Options;

            context = new CACIDBContext(options);
 
            context.Database.EnsureDeleted();  // this removed the error between the several GET test methods. but not the delete,update
            context.AppSettings.Add(new AppSettings { myId = 1, MyName = "test1", MyValue = "test1" });
            context.AppSettings.Add(new AppSettings { myId = 2, MyName = "test2", MyValue = "test2" });
            context.AppSettings.Add(new AppSettings { myId = 3, MyName = "test3", MyValue = "test3" });

            context.SaveChanges();
             
        }

[TestMethod]
        public void GetSettings()
        {
            var logger = new Mock<ILogger<SettingsRepository>>();
            var caciDbContent = new Mock<CACIDBContext>();
            sRepository settingRepository = null;

            settingRepository = new sRepository (context, logger.Object);
            List<AppSettings> settings = settingRepository.GetSettings().ToList();
            Assert.AreEqual(3, settings.Count);
        }

        [TestMethod]
        public void RemoveSetting()
        {
            var logger = new Mock<ILogger<sRepository>>();
            var caciDbContent = new Mock<CACIDBContext>();
            sRepository sRepository = null;
 

            sRepository = new sRepository (context, logger.Object);
                // test Get By AppSettingName
                bool result = sRepository.RemoveSetting(new AppSettings { myId  = 3, MyName = "test3", MyValue = "test3");
                Assert.AreEqual(true, result);
 
        }



Here is my c# code

        public bool RemoveSetting(AppSettings setting)
        {
            try
            {
                myDbContent.AppSettings.Remove(setting);
            }
            catch (Exception ex)
            {
                logger.LogError($"Failed to removfe an existing appsetting: {ex}");
                throw ex;
            }

            return (myDbContent.SaveChanges() > 0 ? true : false);
        }

标签: visual-studiounit-testingmoq

解决方案


添加以下行对我的情况有所帮助,这与您的情况相似。

context.ChangeTracker.Clear()

但它仅适用于 EF Core 5.0。来源:微软文档


推荐阅读