In my MVC4 application almost every method does something with a database. 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.
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
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.
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. By using DI you can mock the projectContext class and make it return whatever you need. Check out Autofac ( http://www.codeproject.com/Articles/25380/Dependency-Injection-with-Autofac ), it might already be installed in you mvc solution.
Your problem is that your ShoppingCart
class is directly coupled with the database layer.
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.
Depend on abstractions...
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.