2014-09-23 65 views
0

我有一个类似于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(); 

回答

0

坦率地说,我发现测试这种行为真的很困难。我建议你看一下DbContext在内存中打包的解决方案,比如the Effort library

我解释了如何在this answer中使用它:它是针对实体框架的,但我认为在您的情况下可以使用相同的行为。

+0

谢谢你的回答,但是我最终使用了我之前忽略的codeplex链接中的一个类,InMemoryDbSet 为我所需要的工作:http://entityframework.codeplex.com/SourceControl/latest#test /EntityFramework/FunctionalTests/TestDoubles/InMemoryDbSet.cs – akousmata 2014-09-25 18:25:25