Moq Mocking with Identity 2.0数据库 [英] Moq Mocking with Identity 2.0 Database
问题描述
IdentityDbContext :(从简单成员DbContext修改)
public class MyDb:IdentityDbContext< ApplicationUser> // DbContext
{
public MyDb():base(MyApplication){}
// public virtual DbSet< UserProfile> UserProfiles {get;组; }
public virtual DbSet& BusAcnt> BusAcnts {get;组; } //标记为虚拟允许嘲笑覆盖
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,NmOfc = 1,Status =Active},
new BusAcnt {Id = 2,CmpnyName =Company 3,NmOfc = 1,Status =Active},
new BusAcnt {Id = 3,CmpnyName =Company 4,NmOfc = 1,Status =Active},
new BusAcnt {Id = 4,CmpnyName =Company 5,NmOfc = 1,Status =Active},
新的BusAcnt {Id = 5,CmpnyName =Company 6,NmOfc = 1,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())返回(dataBa.GetEnumerator());
var MyDb = new Mock< MyDb>();
mockMyDb.Setup(c => c.BusAcnts).Returns(mockSetBa.Object);
return mockMyDb;
}
}
集成测试:
[事实]
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)))
)。返回(真);
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.ModelValidationException在模型生成期间检测到一个或多个验证错误:
Castle.Proxies。 IdentityUserRole::EntityType'IdentityUserRole'没有定义键。定义此EntityType的键。
Castle.Proxies.IdentityUserLogin::EntityType'IdentityUserLogin'没有定义键。定义此EntityType的键。
IdentityUserRoles:EntityType:EntitySet'IdentityUserRoles'基于没有定义键的类型'IdentityUserRole'。
IdentityUserLogins:EntityType:EntitySet'IdentityUserLogins'基于没有定义键的IdentityUserLogin类型。 System.Data.Entity.Core.Metadata.Edm.EdmModel.Validate()
在System.Data.Entity.DbModelBuilder.Build(DbProviderManifest providerManifest,DbProviderInfo providerInfo)
在System。 Data.Entity.DbModelBuilder.Build(DbConnection providerConnection)
在System.Data.Entity.Internal.LazyInternalContext.CreateModel(LazyInternalContext internalContext)
在System.Data.Entity.Internal.RetryLazy`2.GetValue( TInput输入)
在System.Data.Entity.Internal.LazyInternalContext.InitializeContext()
在System.Data.Entity.Internal.InternalContext.CreateObjectContextForDdlOps()
在System.Data.Entity。 Database.Exists()
在Microsoft.AspNet.Identity.EntityFramework.IdentityDbContext`1.IsIdentityV1Schema(DbContext db)
在Microsoft.AspNet.Identity.EntityFramework.IdentityDbContext`1..ctor(String nameOrConnectionString, Boolean throwIfV1Schema)
在Microsoft.AspNet.Identity.EntityFramework.IdentityDbContext`1..ctor(String在MyDb.cs中的MyApplication.Models.MyDb..ctor()中的
$ 9
在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
或有没有人想知道如何做到这一点,链接到嘲弄一个Identity 2.0数据库的文档。 ApplicationUser
。
<会特别有帮助吗?
谢谢Jamie,反过来Andreas在测试框架说实体没有为内置实体定义关键字。
在 MockDbSetup
中的 MockMyDb()
{CallBase = true};
to var MyDb = new Mock< MyDb>();
导致
var MyDb = new Mock< MyDb>(){CallBase = true};
I successfully set up an Integration Test using mocking with Moq against my BusAct controller in an MVC 5, Entity Framework 6 app based on a Simple membership database. But now I have migrated the database to Identity 2.0 and replaced the UserProfile with ApplicationUser.
IdentityDbContext: (Modified from Simple membership 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", NmOfc = 1, Status = "Active"},
new BusAcnt {Id = 2, CmpnyName = "Company 3", NmOfc = 1, Status = "Active"},
new BusAcnt {Id = 3, CmpnyName = "Company 4", NmOfc = 1, Status = "Active"},
new BusAcnt {Id = 4, CmpnyName = "Company 5", NmOfc = 1, Status = "Active"},
new BusAcnt {Id = 5, CmpnyName = "Company 6", NmOfc = 1, 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;
}
}
Integration Test:
[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);
}
When I run the test now I get these errors:
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[])
I believe I need to modify the MockDbSetup but have not been able to find any information on how to do that.
I tried adding
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());
But I get a "Can't resolve" error on GetEnumerator
And neither
mockMyDb.Setup(c => c.AspNetUsers).Returns(mockSetUsr.Object);
or
mockMyDb.Setup(c => c.ApplicationUser).Returns(mockSetUsr.Object);
works because it cannot resolve either AspNetUsers
or ApplicationUser
.
Does anyone have an idea of how to do this, links to documentation on mocking an Identity 2.0 database would be especially helpful?
Thank you to Jamie and in turn Andreas' answer at Testing framework says entity has no key defined for built in entity.
In the MockMyDb()
method in MockDbSetup
add { CallBase = true };
to var MyDb = new Mock<MyDb>();
resulting in
var MyDb = new Mock<MyDb>() { CallBase = true };
这篇关于Moq Mocking with Identity 2.0数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!