2014-09-23 66 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