Moq can’t mock internal methods

Today I was trying to mock a concrete class that had an internal method that I wanted to set the return value for. After much frustration, I discovered that (Google’s) Moq 4.0.10827.0 won’t intercept internal methods.

Consider the code below, the WorksGreat() test calls the Explode() method which is intercepted properly and doesn’t actually call the Bomb.Explode() method.

The ThrowsTheBOOMException() method, even though I’ve told Moq that when InternalExplode is called that it should return 1, it still calls InternalExplode and it does throw the exception.

using System;
using Moq;
using NUnit.Framework;

namespace MoqTester
{
    [TestFixture]
    public class InternalMethodsTest
    {
        [Test]
        public void WorksGreat()
        {
            var bombMock = new Mock<Bomb>();
            var bomber = new Bomber(bombMock.Object);

            bomber.PushTrigger();
            bombMock.Verify(b => b.Explode(), Times.Once());
        }

        [Test]
        public void ThrowsTheBOOMException()
        {
            var bombMock = new Mock<Bomb>();
            bombMock.Setup(b => b.InternalExplode()).Returns(1);
            var bomber = new Bomber(bombMock.Object);

            bomber.InternalPushTrigger();
            bombMock.Verify(b => b.InternalExplode(), Times.Once());
        }
    }

    public class Bomb
    {
        public virtual int Explode()
        {
            return InternalExplode();
        }

        internal virtual int InternalExplode()
        {
            throw new Exception("BOOM!");
        }
    }

    public class Bomber
    {
        private readonly Bomb _bomb;

        public Bomber(Bomb bomb)
        {
            _bomb = bomb;
        }

        public void PushTrigger()
        {
            _bomb.Explode();
        }

        public void InternalPushTrigger()
        {
            _bomb.InternalExplode();
        }
    }
}
This entry was posted in Development, Uncategorized and tagged . Bookmark the permalink.