Skip to main content

Migrating to Mockolate

Coming from Moq, NSubstitute or FakeItEasy? There are two ways to move your tests over:

  • Automatically: for Moq and NSubstitute, the Mockolate.Migration package reports every mock it can migrate and rewrites it with a code fix.
  • By hand: this page shows the same test in each library and translates the most common calls.

Select the library you know; the choice applies to all examples on this page.

Side by side​

All examples use this interface:

public delegate void ChocolateDispensedDelegate(string type, int amount);
public interface IChocolateDispenser
{
int this[string type] { get; set; }
int TotalDispensed { get; set; }
bool Dispense(string type, int amount);
event ChocolateDispensedDelegate ChocolateDispensed;
}
Moq
// Setup
Mock<IChocolateDispenser> mock = new Mock<IChocolateDispenser>();
mock.Setup(x => x.Dispense("Dark", 2)).Returns(true);
mock.SetupGet(x => x["Dark"]).Returns(10);

// Usage
int available = mock.Object["Dark"];
bool success = mock.Object.Dispense("Dark", 2);
mock.Raise(m => m.ChocolateDispensed += null, "Dark", 2);

// Verification
mock.Verify(x => x.Dispense("Dark", 2), Times.Once());
mock.VerifyGet(x => x["Dark"], Times.Once());
Mockolate
// Setup
IChocolateDispenser dispenser = IChocolateDispenser.CreateMock();
dispenser.Mock.Setup.Dispense("Dark", 2).Returns(true);
dispenser.Mock.Setup["Dark"].Returns(10);

// Usage
int available = dispenser["Dark"];
bool success = dispenser.Dispense("Dark", 2);
dispenser.Mock.Raise.ChocolateDispensed("Dark", 2);

// Verification
dispenser.Mock.Verify.Dispense("Dark", 2).Once();
dispenser.Mock.Verify["Dark"].Got().Once();

Translation table​

MoqMockolate
new Mock<T>()T.CreateMock()
mock.Objectthe mock itself
new Mock<T>(MockBehavior.Strict)T.CreateMock(MockBehavior.Default.ThrowingWhenNotSetup())
new Mock<T>(arg1, arg2)T.CreateMock([arg1, arg2])
mock.As<IOther>()T.CreateMock().Implementing<IOther>()
mock.CallBase = truethe default for class mocks; turn it off with SkippingBaseClass()
It.IsAny<T>()It.IsAny<T>()
It.Is<T>(x => …)It.Satisfies<T>(x => …)
It.IsIn(a, b), It.IsInRange(a, b, Range.Inclusive)It.IsOneOf(a, b), It.IsInRange(a, b)
It.IsRegex(pattern)It.Matches(pattern).AsRegex()
.Returns(…), .ReturnsAsync(…), .Throws<T>().Returns(…), .ReturnsAsync(…), .Throws<T>()
SetupSequence(…).Returns(a).Returns(b)Setup.X(…).Returns(a).Returns(b)
.Callback(…).Do(…)
mock.SetupProperty(x => x.P, 42)Mock.Setup.P.InitializeWith(42)
mock.SetupGet(x => x.P).Returns(42)Mock.Setup.P.Returns(42)
mock.Protected().Setup<bool>("Name", …)Mock.SetupProtected.Name(…)
mock.Raise(x => x.E += null, …)Mock.Raise.E(…)
mock.Verify(x => x.M(…), Times.Once())Mock.Verify.M(…).Once()
Times.Never(), Times.AtLeastOnce(), Times.Exactly(n).Never(), .AtLeastOnce(), .Exactly(n)
mock.VerifyGet(x => x.P), mock.VerifySet(x => x.P = 42)Mock.Verify.P.Got(), Mock.Verify.P.Set(42)
mock.VerifyNoOtherCalls()Mock.VerifyThatAllInteractionsAreVerified() (returns a bool)
Differences to watch out for
  • A Returns/Throws sequence starts over after its last entry. Mark the last entry with .Forever() to keep repeating it instead.
  • Class mocks call the base class implementation by default, even when a setup matches. See Core concepts.
  • A later setup with the same arguments replaces an earlier one, so chain everything that belongs to one setup.

For the complete Mockolate syntax on one page, see the cheat sheet.