使用 ApplicationDbContext 进行单元测试帐户控制器
Posted
技术标签:
【中文标题】使用 ApplicationDbContext 进行单元测试帐户控制器【英文标题】:Unit Testing Account controller with ApplicationDbContext 【发布时间】:2015-07-12 10:03:31 【问题描述】:我是单元测试的初学者,在使用 ApplicationDbContext 的帐户控制器中测试我的一些方法时遇到问题。我一直在关注本教程: http://www.asp.net/web-api/overview/testing-and-debugging/mocking-entity-framework-when-unit-testing-aspnet-web-api-2 但我似乎无法访问与 applicationUser 相关的一些变量。在我的帐户控制器中,我可以访问从其超类“IdentityUser”继承的 ID、用户名、电子邮件等,但由于某种原因,我似乎无法在我的测试控制器中访问这些变量。到目前为止,我有以下实现:
interface IStoreAppContext : IDisposable
DbSet<ApplicationUser> Users get;
int SaveChanges();
void MarkAsModified(ApplicationUser item);
我的 IdentityModel 类:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>, IStoreAppContext
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
public static ApplicationDbContext Create()
return new ApplicationDbContext();
public DbSet<SportProgram> SportContext get; set;
public DbSet<Exercise> ExerciseContext get; set;
public DbSet<ExerciseImage> ExerciseImageContext get; set;
public DbSet<Store> StoreContext get; set;
public void MarkAsModified(ApplicationUser item)
Entry(item).State = EntityState.Modified;
我已将以下内容添加到我的 AccountController:
private IStoreAppContext db2 = new ApplicationDbContext();
// add these contructors
public AccountController()
public AccountController(IStoreAppContext context)
db2 = context;
在我的测试项目中:
class TestProductDbSet : TestDbSet<ApplicationUser>
public override ApplicationUser Find(params object[] keyValues)
return this.SingleOrDefault(user => user. == (int)keyValues.Single());
上面的返回行是我遇到此问题的第一个地方。我有“user => user.”,当 Visual Studio 在“.”之后提供我的建议时ApplicationUser 类给我的所有变量都是我添加的变量,我似乎无法访问从 IdentityUser 类继承的 ApplicationUser Id、用户名、电子邮件。有人可以帮忙吗?
这是我的测试项目中的另一个类,可以帮助你:
class TestStoreAppContext : IStoreAppContext
public TestStoreAppContext()
this.Products = new TestProductDbSet();
public DbSet<ApplicationUser> Products get; set;
public int SaveChanges()
return 0;
public void MarkAsModified(ApplicationUser item)
public void Dispose()
【问题讨论】:
【参考方案1】:这里的关键思想是您将 EntityFramework 访问替换为集合,以便您可以使用 LINQ for Objects 而不是 LINQ to Entities,例如验证查询的逻辑。
所以你的TestProductDbSet
应该有一个集合成员(ApplicationUser
),它将充当数据库。所以你应该为它填充一些数据。
然后在您的单元测试中,您应该使用TestStoreAppContext
创建AccountController
。
【讨论】:
感谢您的回复。所以你是说我应该在我的 TestProductDbSer 类中硬编码值,比如一个 ApplicationUsers 列表?但是为什么我不能访问那些从 IdentityUser 类继承的变量,例如 Id、用户名等? 是的,这是获取数据的最简单方法。您还可以使用构造函数或属性来设置/覆盖每个测试类中的集合。我不确定为什么您看不到您的属性。他们是否有可能是internal
而 TestDbSet
在另一个程序集或命名空间中您是否尝试过手动键入它们以确保这不仅仅是 IntelliSense 的一些问题?
我已经创建了一个 ApplicationUser 集合,并按照您的建议创建了一个带有 TestStoreAppContext 的 AccountController。我在“参数名称:请求”的测试方法中遇到空指针异常。在网上搜索后,我通过在我的方法中添加以下行找到了一个解决方案: var request = new HttpRequestMessage(HttpMethod.Post, "62214/api/Account/Register/Password-1"); controller.Request = request; 但随后我收到一个带有“参数”的空指针异常name: Context". //下面继续评论
我添加了以下行 controller.ControllerContext = new System.Web.Http.Controllers.HttpControllerContext();但随后我再次收到“参数名称:请求”的相同空错误。有任何想法吗?似乎无法弄清楚。整个方法在下一条评论中。 (对不起,我在评论中达到了字符限制)
[TestMethod()] public async Task PostRegisterTest() var controller = new AccountController(new TestStoreAppContext()); var item = GetDemoProduct(); var 密码 = "密码-1"; var request = new HttpRequestMessage(HttpMethod.Post, "62214/api/Account/Register/Password-1"); controller.Request = request; var response = await controller.PostRegister(password, item) as OkNegotiatedContentResult; Assert.AreEqual(response.Content.UserName,项目。用户名);以上是关于使用 ApplicationDbContext 进行单元测试帐户控制器的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Asp .Net 5 的控制器外使用 ApplicationDbContext
ASP.NET 核心标识。使用 ApplicationDbContext 和 UserManager。他们是不是共享上下文?
无法创建“applicationdbcontext”类型的对象。对于设计时支持的不同模式错误
现有数据库上的 AspNet Identity ApplicationDbContext