加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

单元测试 – Moq Mocking with Identity 2.0 Database

发布时间:2020-12-16 06:27:54 所属栏目:asp.Net 来源:网络整理
导读:我在基于Simple成员资格数据库的MVC 5,Entity Framework 6应用程序中使用Moq对我的BusAct控制器进行了模拟,成功地设置了集成测试.但现在我已将数据库迁移到Identity 2.0并将UserProfile替换为ApplicationUser. IdentityDbContext :(从简单成员资格DbContext
我在基于Simple成员资格数据库的MVC 5,Entity Framework 6应用程序中使用Moq对我的BusAct控制器进行了模拟,成功地设置了集成测试.但现在我已将数据库迁移到Identity 2.0并将UserProfile替换为ApplicationUser.

IdentityDbContext :(从简单成员资格DbContext修改)

public class MyDb : IdentityDbContext<ApplicationUser> // DbContext  
  {
    public MyDb () : base("MyApplication") { }

    // public virtual DbSet<UserProfile> UserProfiles { get; set; }
    public virtual DbSet<BusAcnt> BusAcnts { get; set; } // marking as virtual allows mocking override
    public virtual DbSet<...>
    ...

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
      base.OnModelCreating(modelBuilder);
      modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
    }
  }

MockDbSetup:

public class MockDbSetup
  {
    public static Mock<MyDb> MockMyDb()
    {
      var dataBa = new List<BusAcnt>  {
        new BusAcnt {Id = 0,CmpnyName = "Company 1",NmOfc = 1,Status = "Active"},new BusAcnt {Id = 1,CmpnyName = "Company 2",new BusAcnt {Id = 2,CmpnyName = "Company 3",new BusAcnt {Id = 3,CmpnyName = "Company 4",new BusAcnt {Id = 4,CmpnyName = "Company 5",new BusAcnt {Id = 5,CmpnyName = "Company 6",Status = "Active"}
      }.AsQueryable();
      var mockSetBa = new Mock<DbSet<BusAcnt>>();
      mockSetBa.As<IQueryable<BusAcnt>>().Setup(m => m.Provider).Returns(dataBa.Provider);
      mockSetBa.As<IQueryable<BusAcnt>>().Setup(m => m.Expression).Returns(dataBa.Expression);
      mockSetBa.As<IQueryable<BusAcnt>>().Setup(m => m.ElementType).Returns(dataBa.ElementType);
      mockSetBa.As<IQueryable<BusAcnt>>().Setup(m => m.GetEnumerator()).Returns(dataBa.GetEnumerator());
      var MyDb = new Mock<MyDb>();
      mockMyDb.Setup(c => c.BusAcnts).Returns(mockSetBa.Object);
      return mockMyDb;
    }
  }

整合测试:

[Fact]
public void GetAllBusAcnt()
{
  var mockMyDb = MockDBSetup.MockMyDb();
  var controller = new BusAcntController(mockMyDb.Object);
  var controllerContextMock = new Mock<ControllerContext>();
  controllerContextMock.Setup(
      x => x.HttpContext.User.IsInRole(It.Is<string>(s => s.Equals("admin")))
      ).Returns(true);
  controller.ControllerContext = controllerContextMock.Object;

  var viewResult = controller.Index() as ViewResult;
  var model = viewResult.Model as PagedBusIdxModel;

  Assert.NotNull(model);
  Assert.Equal(6,model.BusAcnts.ToList().Count());
  Assert.Equal("Company 2",model.BusAcnts.ToList()[1].CmpnyName);
}

当我运行测试时,我得到这些错误:

System.Data.Entity.ModelConfiguration.ModelValidationExceptionOne or more validation errors were detected during model generation:

Castle.Proxies.IdentityUserRole: : EntityType 'IdentityUserRole' has no key defined. Define the key for this EntityType.
Castle.Proxies.IdentityUserLogin: : EntityType 'IdentityUserLogin' has no key defined. Define the key for this EntityType.
IdentityUserRoles: EntityType: EntitySet 'IdentityUserRoles' is based on type 'IdentityUserRole' that has no keys defined.
IdentityUserLogins: EntityType: EntitySet 'IdentityUserLogins' is based on type 'IdentityUserLogin' that has no keys defined.
   at System.Data.Entity.Core.Metadata.Edm.EdmModel.Validate()
   at System.Data.Entity.DbModelBuilder.Build(DbProviderManifest?providerManifest,?DbProviderInfo?providerInfo)
   at System.Data.Entity.DbModelBuilder.Build(DbConnection?providerConnection)
   at System.Data.Entity.Internal.LazyInternalContext.CreateModel(LazyInternalContext?internalContext)
   at System.Data.Entity.Internal.RetryLazy`2.GetValue(TInput?input)
   at System.Data.Entity.Internal.LazyInternalContext.InitializeContext()
   at System.Data.Entity.Internal.InternalContext.CreateObjectContextForDdlOps()
   at System.Data.Entity.Database.Exists()
   at Microsoft.AspNet.Identity.EntityFramework.IdentityDbContext`1.IsIdentityV1Schema(DbContext?db)
   at Microsoft.AspNet.Identity.EntityFramework.IdentityDbContext`1..ctor(String?nameOrConnectionString,?Boolean?throwIfV1Schema)
   at Microsoft.AspNet.Identity.EntityFramework.IdentityDbContext`1..ctor(String?nameOrConnectionString)
   at MyApplication.Models.MyDb..ctor() in MyDb.cs: line 9
   at Castle.Proxies.MyDbProxy..ctor(IInterceptor[])

我相信我需要修改MockDbSetup但是却无法找到有关如何执行此操作的任何信息.

我尝试添加

var dataUsr = new List<ApplicationUser>
  {
    new ApplicationUser { UserName = "Test",PasswordHash = "a123cdefg"} }.AsQueryable();
  var mockSetUsr = new Mock<DbSet<ApplicationUser>>();
  mockSetUsr.As<IQueryable<BusAcnt>>().Setup(m => m.Provider).Returns(dataUsr.Provider);
  mockSetUsr.As<IQueryable<BusAcnt>>().Setup(m => m.Expression).Returns(dataUsr.Expression);
  mockSetUsr.As<IQueryable<BusAcnt>>().Setup(m => m.ElementType).Returns(dataUsr.ElementType);
  mockSetUsr.As<IQueryable<BusAcnt>>().Setup(m => m.GetEnumerator()).Returns(dataUsr.GetEnumerator());

但是我在GetEnumerator上遇到“无法解决”错误

而且都没有

mockMyDb.Setup(c => c.AspNetUsers).Returns(mockSetUsr.Object);

要么

mockMyDb.Setup(c => c.ApplicationUser).Returns(mockSetUsr.Object);

因为它无法解析AspNetUsers或ApplicationUser而起作用.

有没有人知道如何做到这一点,关于模拟Identity 2.0数据库的文档链接会特别有用吗?

解决方法

谢谢杰米,反过来安德烈斯在 Testing framework says entity has no key defined for built in entity.回答

在MockDbSetup中的MockMyDb()方法中添加{CallBase = true}; to var MyDb = new Mock< MyDb>();导致

var MyDb = new Mock<MyDb>() { CallBase = true };

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读