简体   繁体   中英

why MOQ framework overrides all virtual methods - c#

I'm new to MOQ in c#. Here is my code:

   public class CustomerBase
    {
        private List<Customer> customers = new List<Customer>();
        public const int MAX_CUSTOMERS = 100;

        public int CustomerCount()
        {
            return customers.Count();
        }

        public void AddCustomer(string name, string email)
        {
            if (CustomerCount() >= MAX_CUSTOMERS)
            {
                return;
            }
            Customer cus = new Customer(name);
            customers.Add(cus);
            SendEmail(email);
        }

        public virtual void SendEmail(string email)
        {
            throw new NotImplementedException();
        }
    }

    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestAddUser()
        {
            Mock<CustomerBase> m = new Mock<CustomerBase>();
            m.Setup(x => x.SendEmail("k")).Verifiable(); // bypass send email because email is server is not setup
            m.Object.AddCustomer("max", "k@g");
            Assert.AreEqual(1, m.Object.CustomerCount());
        }
  }

The test passes. As soon as I make the CustomerCount virtual, the test fails because it that method starts to return zero. Does anyone know why and how to prevent this behaviour?


Updated code - using internal assembly fails:

   [assembly: InternalsVisibleTo("UnitTestProject1")] // make the test assembly internal
namespace MoqSmple1
{
    public class CustomerBase
    {
        private List<Customer> customers = new List<Customer>();
        public const int MAX_CUSTOMERS = 100;

        internal virtual int CustomerCount()
        {
            return customers.Count();
        }

        public void AddCustomer(string name, string email)
        {
            if (CustomerCount() >= MAX_CUSTOMERS)
            {
                return;
            }
            Customer cus = new Customer(name);
            customers.Add(cus);
            SendEmail(email);
        }

        internal virtual void SendEmail(string email)
        {
            throw new NotImplementedException();
        }
    }
}

namespace UnitTestProject1
{
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestAddUser()
        {
            Mock<CustomerBase> m = new Mock<CustomerBase>();
            m.Setup(x => x.SendEmail("k")).Verifiable(); // bypass send email because email is server is not setup
            m.Object.AddCustomer("max", "k@g");
            m.CallBase = true;// keep the default behaviour of virtual methods except the ones skipped
            Assert.AreEqual(1, m.Object.CustomerCount());
        }
    }
}

update I figured out:

  • I needed a public key
  • I needed to make the methods internal protected virtual

You want to set <YourMock>.CallBase = true . Here is a good article on CallBase

In a nutshell, Moq will create a proxy for all virtual methods by default, and setting CallBase to true keeps the default implementation unless you explicitly ask for a proxy.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM