Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: ASP.NET MVC3 unit
Hi,
 
I have a unit of work class which is as below:
 
public class UnitOfWork : IUnitOfWork, IDisposable
    {
        private readonly EFDbContext context;
        private IGenericRepository<Category> _categoryRepository;
        private IGenericRepository<Product> _productRepository;
 

        #region Contructor
        public UnitOfWork()
        {
            context = new EFDbContext();
        }
        #endregion
 
        public IGenericRepository<Category> CategoryRepository
        {
            get
            {
                if (_categoryRepository == null)
                {
                  _categoryRepository = new EFGenericRepository<Category>(context);
                }
                return _categoryRepository;
            }
        }
 
        public IGenericRepository<Product> ProductRepository
        {
            get
            {
                if (_productRepository == null)
                {
                    _productRepository = new EFGenericRepository<Product>(context);
                }
                return _productRepository;
            }
        }
 
        // Save.. Dispose etc omitted
    }// end of class
 
I defined a new Interface, IPriceIncreaser. Purpose: Increase prices of all products in Product inventory
 
public class PriceIncreaser : IPriceIncreaser
    {
        private IUnitOfWork unitOfWork;
 
        public PriceIncreaser(IUnitOfWork unitOfWorkParam)
        {
            unitOfWork = unitOfWorkParam;
        }
 
        public void IncreasePrice(decimal increaseAmount)
        {
            foreach (Product p in unitOfWork.ProductRepository.Get())
            {
                p.Price += increaseAmount;
            }
        }
    }
 
Now, i want to unit test my repo, using Moq as the unit testing framework.
 
I've written the following unit test:
 
[TestMethod]
        public void Can_Increase_Prices()
        {
           
 
            var mockProductRepo = new Mock<IGenericRepository<Product>>();
            mockProductRepo.Object.Insert(new Product { Name = "MP", Description  ="HI", Price = 2500 });
             
            // mock Unit of work here...
           
 
            decimal initalProductTotalPrice = mockUnitOfWork.Object.ProductRepository.Get().Sum(p => p.Price);
 
            decimal increaseAmount = 55;
 
            // Act:
            PriceIncreaser target = new PriceIncreaser(mockUnitOfWork.Object);
            target.IncreasePrice(increaseAmount);
 
            // Assert
            Assert.AreNotEqual(initalProductTotalPrice, mockUnitOfWork.Object.ProductRepository.Get().Sum(p => p.Price));
        }
 

But i'm getting an error when i run the test which says:
 
Cannot override Non-Virtual member ...ProductRepository
 
I realize from reading other threads that Moq will only mock Interfaces, and abstract methods/fields.
 
I want to know how i can now write a unit test, which mocks my Product repository, which is of type IGenericRepository<Product> contained within UnitOfWork.ProductRepository and UnitOfWork is-a IUnitOfWork.
 
Any and all suggestions appreciated.
 
Thanks.
Posted 5-Jul-12 9:24am

1 solution

Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

The error "Cannot override Non-Virtual member ...ProductRepository" indicates that Moq is attempting "override" a method that is not virtual. So a method w/ definition
 
public void Something() { ... }
 
cannot be overridden. But this can be :
 
public virtual void Something() { ... }
 
Check out the following that discusses about overriding a virtual method when using Moq.
 
http://stackoverflow.com/questions/3539278/using-moq-to-override-virtual-methods-in-the-same-class[^]
  Permalink  

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



Advertise | Privacy | Mobile
Web03 | 2.8.1411022.1 | Last Updated 5 Jul 2012
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100