我想測試下面的方法:如何使用視圖模型嘲笑方法MVC4與實體框架4.0
public ActionResult Index()
{
var transactions = db.Transactions.Include(t => t.User)
.GroupBy(t => t.UserId)
.Select(group => new TransactionViewModel
{
User = group.FirstOrDefault().User.FullName,
UserId = group.FirstOrDefault().UserId,
Total = (group.Sum(t => t.TransactionAmount))
});
// Show lowest balance first
return View(transactions.ToList());
}
這裏Transaction
模型具有Orders
列表,有一個外鍵User
和一些更多的屬性見:
public class Transaction
{
public int TransactionId { get; set; }
public DateTime Date { get; set; }
public int UserId { get; set; }
public List<Order> Orders { get; set; }
public decimal TransactionAmount { get; set; }
public virtual User User { get; set; }
}
的TransactionViewModel
如下所示:
public class TransactionViewModel
{
public string User { get; set; }
public int UserId { get; set; }
public decimal Total { get; set; }
}
和用於計算屬於用戶不同交易的Total
。
爲了測試這個方法我有一個FakeDbSet
並使用FakeContext
(這在其他控制器的測試都工作)在以下設置:
[TestClass]
public class TransactionControllerTest
{
TransactionController trController;
[TestInitialize]
public void TransactionControllerTestInitialize()
{
// Arrange
var memoryTransactionItems = new FakeDbSet<Transaction>
{
new Transaction {
Date = DateTime.Today,
TransactionAmount = 5.10M,
UserId = 1,
Orders = new List<Order>{
// Categorie 2 and confirmed
new Order { OrderId = 2,
UnitPrice = 2.00M,
Quantity = 1,
Date = DateTime.Today,
IsConfirmed = true,
User = new User {
Name = "Kees",
FullName="Kees Piet",
Email = "[email protected]",
isAvailable = true,
UserId = 1
},
Product = new Product {
Category = new Category {
CategoryId = 2,
Name = "Categorie2"
},
Name = "Testproduct2",
Price = 2.00M,
Visible = true
}
},
// Categorie 2 and confirmed
new Order { OrderId = 2,
UnitPrice = 1.00M,
Quantity = 1,
Date = DateTime.Today,
IsConfirmed = true,
User = new User {
Name = "Jan",
FullName="Jan Piet",
Email = "[email protected]",
isAvailable = true,
UserId = 2
},
Product = new Product {
Category = new Category {
CategoryId = 2,
Name = "Categorie2"
},
Name = "Testproduct2",
Price = 3.10M,
Visible = true
}
}
}
}
};
// Create mock units of work
var mockData = new Mock<FakeContext>();
mockData.Setup(m => m.Transactions).Returns(memoryTransactionItems);
// Setup controller
trController = new TransactionController(mockData.Object);
}
[TestMethod]
public void TestTransactionIndex()
{
// Invoke
var viewResult = trController.Index() as ViewResult;
var transactionsFromView = (IEnumerable<TransactionViewModel>)viewResult.Model;
// Assert
Assert.AreEqual(1, transactionsFromView.Count(),
"The amount of transactions added to the Index View should be 1.");
}
}
當我運行TestTransactionIndex
我收到以下錯誤:
Test Name: TestTransactionIndex Test Outcome: Failed Test Duration: 0:00:30.6276475
Result Message: Test method Tests.Controllers.TransactionControllerTest.TestTransactionIndex threw exception: System.NullReferenceException: Object reference not set to an instance of an object. Result StackTrace: at lambda_method(Closure , IGrouping
2) at System.Linq.Enumerable.WhereSelectEnumerableIterator
2.MoveNext()
at System.Collections.Generic.List1..ctor(IEnumerable
1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source) at Controllers.TransactionController.Index()
我覺得這很奇怪,因爲我以適當的方式設置了我的模擬單元。我希望有人能解釋我是如何能夠正確地發送FakeDbSet<Transaction>
的觀點,並沒有得到一個NullReferenceException
。
/編輯根據要求,這裏有contructors爲TransactionController
:
private IContext _context;
public TransactionController()
{
_context = new Context();
}
public TransactionController(IContext context)
{
_context = context;
}
您可以發佈從TransactionController – tire0011
建設者@ user1511384是的。完成。 –
在索引方法你有'db.Transactions.Include(T => t.User)',你嘗試過與用戶的假dbSet配置假背景?因爲選擇具有此線'用戶= group.FirstOrDefault()。User.FullName,'將給出一個空引用如果_user_爲空。像'mockData.Setup(M => m.Users).Returns(....)'如果不工作,你可以嘗試在填充你的假交易 –