[英]How can I test methods that interact with a database with Moq?
In my MVC4 application almost every method does something with a database. 在我的MVC4应用程序中,几乎每个方法都使用数据库。 Now I want to test these methods and I looked at this tutorial to do so.
现在我想测试这些方法,我看了这个教程。 It is recommended there to use Moq to make mock objects.
建议在那里使用Moq来制作模拟对象。
In this particular case I want to test my GetTotal
method of the ShoppingCart
class (based on Microsoft Tutorial ) which depends on the AddToCart
method which look like this 在这种特殊情况下,我想测试
ShoppingCart
类的GetTotal
方法(基于Microsoft教程 ),该方法依赖于AddToCart
方法,该方法看起来像这样
public class ShoppingCart() {
projectContext db = new projectContext ();
public virtual void AddToCart(Product product)
{
var cartItem = db.Carts.SingleOrDefault(
c => c.CartId == ShoppingCartId
&& c.ProductId == product.ProductId);
if (cartItem == null)
{
cartItem = new Cart
{
ProductId = product.ProductId,
CartId = ShoppingCartId,
Count = 1,
DateCreated = DateTime.Now
};
db.Carts.Add(cartItem);
}
else
{
cartItem.Count++;
}
db.SaveChanges();
}
public virtual decimal GetTotal()
{
decimal? total = (from cartItems in db.Carts
where cartItems.CartId == ShoppingCartId
select (int?)cartItems.Count *
cartItems.Product.Price).Sum();
return total ?? decimal.Zero;
}
}
As can be seen both methods depend on the projectContext
instance db. 可以看出,两种方法都依赖于
projectContext
实例db。
When testing these methods I wanted to use mock objects like this: 在测试这些方法时,我想使用这样的模拟对象:
[TestClass]
public class ShoppingCartTest : DbContext
{
[TestMethod]
public void GetTotalTest()
{
// Arrange
var _cart = new Mock<ShoppingCart>() { CallBase = true };
var _mock = new Mock<Product>() { CallBase = true };
_mock.SetupGet(m => m.Price).Returns(10.00M);
// Act
_cart.AddToCart() // cannot find method since no definiton can be found
// Assert
Assert.AreEqual(10.00M, _cart.GetTotal());// cannot find GetTotal method since no definiton can be found
}
}
How can I possibibly test these methods? 我怎样才能可能测试这些方法? Is it possible to just create a "fake" database and use that?
是否可以创建一个“假的”数据库并使用它? Or can I adjust the mock objects in a way that methods can be used on them (using "mock methods" seems to me like missing the point of testing the actual methods...)?
或者我可以调整模拟对象的方式可以使用方法(使用“模拟方法”似乎我错过了测试实际方法的点......)?
Testing this is hard, and I'm not sure it's possible to mock this. 测试这很难,我不确定是否可以嘲笑它。 If you can use DI (Dependency Injection) you solve all your problems.
如果您可以使用DI(依赖注入),您可以解决所有问题。 By using DI you can mock the projectContext class and make it return whatever you need.
通过使用DI,您可以模拟projectContext类并使其返回您需要的任何内容。 Check out Autofac ( http://www.codeproject.com/Articles/25380/Dependency-Injection-with-Autofac ), it might already be installed in you mvc solution.
查看Autofac( http://www.codeproject.com/Articles/25380/Dependency-Injection-with-Autofac ),它可能已经安装在您的mvc解决方案中。
Your problem is that your ShoppingCart
class is directly coupled with the database layer. 您的问题是您的
ShoppingCart
类直接与数据库层耦合。
Hide your dependency on the concrete projectContext
behind an abstraction, for example an interface, so you can replace it when testing the production code that use it. 隐藏对抽象背后的具体
projectContext
依赖,例如接口,因此您可以在测试使用它的生产代码时替换它。
Depend on abstractions... 取决于抽象......
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.