如何测试项目是否添加到模拟的DbContext?
问题描述:
我有一个类似于this one的问题。如何测试项目是否添加到模拟的DbContext?
但是,在我的情况下,没有任何答案可以接受。我已经实施了几个Microsoft建议的类别here,并且一直在努力处理我认为很常见的场景。
我需要测试在控制器操作中创建的项目是否正确保存到数据库。这里是控制器的方法:
[HttpPost]
[ActionName("CreateUser")]
public virtual async Task<IHttpActionResult> CreateUser(RegisterViewModel viewModel)
{
ApplicationUser user = new ApplicationUser(false, true, true, viewModel.UserName,
viewModel.FirstName, viewModel.LastName, viewModel.EmailAddress);
try
{
user.Salt = HashUtilities.GetSalt();
user.Password = HashUtilities.GetHashedValue(viewModel.Password, user.Salt);
// This is what I want to assert happened
_dbContext.ApplicationUsers.Add(user);
await _dbContext.SaveChangesAsync();
return Ok(user);
}
catch (DbEntityValidationException ex)
{
List<string> messages = new List<string>();
foreach (DbEntityValidationResult eve in ex.EntityValidationErrors)
foreach (DbValidationError dve in eve.ValidationErrors)
messages.Add(dve.ErrorMessage);
string message = string.Join("\n\n", messages);
return BadRequest(message);
}
catch (Exception ex)
{
return InternalServerError(ex);
}
}
这里是我的测试。某些类/方法实现,如InMemoryAsyncQueryable
直接从MS对codeplex链接的建议中复制。
// Arrange
var viewModel = new RegisterViewModel
{
ConfirmPassword = "abc123",
EmailAddress = "[email protected]",
FirstName = "Test",
LastName = "User1",
Password = "abc123",
UserName = "TestUser1"
};
var queryableUsers = new List<ApplicationUser>().AsQueryable();
var users = DataUtilities.CreateMockQueryableSet<ApplicationUser>(new InMemoryAsyncQueryable<ApplicationUser>(queryableUsers));
var mockContext = new Mock<MainContext>();
mockContext.Setup(x => x.ApplicationUsers).Returns(users.Object);
var controller = new ApplicationUserController(mockContext.Object);
// Act
var result = controller.CreateUser(viewModel).Result;
// Assert
Assert.IsInstanceOf<OkNegotiatedContentResult<ApplicationUser>>(result);
mockContext.Verify(x => x.SaveChangesAsync());
// Test for persistence to the DbSet this is what is breaking down.
// My ApplicationUsers.Count() is 0 when I'm expecting 1.
Assert.AreEqual(mockContext.Object.ApplicationUsers.Count(), 1);
var testUser = mockContext.Object.ApplicationUsers.First();
答
坦率地说,我发现测试这种行为真的很困难。我建议你看一下DbContext在内存中打包的解决方案,比如the Effort library。
我解释了如何在this answer中使用它:它是针对实体框架的,但我认为在您的情况下可以使用相同的行为。
谢谢你的回答,但是我最终使用了我之前忽略的codeplex链接中的一个类,InMemoryDbSet为我所需要的工作:http://entityframework.codeplex.com/SourceControl/latest#test /EntityFramework/FunctionalTests/TestDoubles/InMemoryDbSet.cs –
akousmata
2014-09-25 18:25:25