Just sharing some of my inconsequential lunch conversations with you... RSS  

Saturday, February 02, 2008

Moq - yet another mocking library

Moq is a simple strongly typed mocking library, designed from ground up for .NET 3.5 with deep C# 3 integration. Here are some sample usage from the quick start:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using Moq;

namespace ConsoleApplication8
{
public interface IFoo
{
int DoInt(int i);
int Do1();
void Execute();
int DoArgument(string str);
int Duplicate(int i);
int ValueProperty { get; }
}

class Program
{
static void Main(string[] args)
{
// ShouldExpectCallReturn
var mock = new Mock<ICloneable>();
var clone = new object();

mock.Expect(x => x.Clone()).Returns(clone);
Assert.AreSame(clone, mock.Object.Clone());

// ShouldExpectCallWithArgument
var mock1 = new Mock<IFoo>();

mock1.Expect(x => x.DoInt(1)).Returns(11);
mock1.Expect(x => x.DoInt(2)).Returns(22);
Assert.AreEqual(11, mock1.Object.DoInt(1));
Assert.AreEqual(22, mock1.Object.DoInt(2));

// ShouldExpectCallWithReferenceLazyEvaluate
int a = 25;
var mock2 = new Mock<IFoo>();

mock2.Expect(x => x.DoArgument(a.ToString())).Returns(() => a);
a = 10;
Assert.AreEqual(10, mock2.Object.DoArgument("10"));

// ShouldExpectReturnPropertyValue
var mock3 = new Mock<IFoo>();
mock3.Expect(x => x.ValueProperty).Returns(25);

Assert.AreEqual(25, mock3.Object.ValueProperty);

// ShouldExpectMethodCallWithVariable
int value = 5;
var mock4 = new Mock<IFoo>();

mock4.Expect(x => x.Duplicate(value)).Returns(() => value * 2);
Assert.AreEqual(value * 2, mock4.Object.Duplicate(value));

// ShouldMatchAnyArgument
var mock5 = new Mock<IFoo>();

mock5.Expect(x => x.Duplicate(It.IsAny<int>())).Returns(() => 5);
Assert.AreEqual(5, mock5.Object.Duplicate(5));
Assert.AreEqual(5, mock5.Object.Duplicate(25));

// ShouldMatchPredicateArgument
var mock6 = new Mock<IFoo>();

mock6.Expect(x => x.Duplicate(It.Is<int>(someValue => someValue < 5 && someValue > 0))).Returns(() => 1);
Assert.AreEqual(1, mock6.Object.Duplicate(3));
Assert.AreEqual(0, mock6.Object.Duplicate(0)); // Invocation on interface member must have a corresponding expectation.

// ShouldExpectCallWithoutReturnValue
var mock7 = new Mock<IFoo>();

mock7.Expect(x => x.Execute());
mock7.Object.Execute();

// ShouldThrowIfExpectingThrows
var mock8 = new Mock<IFoo>();

mock8.Expect(x => x.Do1()).Throws(new FormatException());
mock8.Object.Do1(); // One of the identified items was in an invalid format.

// ShouldExecuteCallbackWhenVoidMethodIsCalled
var mock9 = new Mock<IFoo>();
bool called = false;

mock9.Expect(x => x.Execute()).Callback(() => called = true);
mock9.Object.Execute(); Assert.IsTrue(called);

// ShouldExecuteCallbackWhenNonVoidMethodIsCalled
var mock10 = new Mock<IFoo>();
bool called1 = false;

mock10.Expect(x => x.Do1()).Callback(() => called1 = true).Returns(1);
Assert.AreEqual(1, mock10.Object.Do1());
Assert.IsTrue(called1);

// ShouldExpectRanges
var mock11 = new Mock<IFoo>();

mock11.Expect(x => x.DoInt(It.IsInRange(1, 5, Range.Inclusive))).Returns(1);
mock11.Expect(x => x.DoInt(It.IsInRange(6, 10, Range.Exclusive))).Returns(2);
Assert.AreEqual(1, mock11.Object.DoInt(1));
Assert.AreEqual(1, mock11.Object.DoInt(2));
Assert.AreEqual(1, mock11.Object.DoInt(5));
Assert.AreEqual(2, mock11.Object.DoInt(7));
Assert.AreEqual(2, mock11.Object.DoInt(9));
}
}
}

Moq offers the following features:



  • Strong-typed: no strings for expectations, no object-typed return values or constraints
  • Unsurpassed VS intellisense integration: everything supports full VS intellisense, from setting expectations, to specifying method call arguments, return values, etc.
  • No Record/Reply idioms to learn. Just construct your mock, set your expectations, use it and optionally verify them
  • Granular control over mock behavior with a simple MockBehavior enumeration (no need to learn what's the theoretical difference between a mock, a stub, a fake, a dynamic mock, etc.)
  • Mock both interfaces and classes
  • Override expectations: can set default expectations in a fixture setup, and override as needed on tests
  • Pass constructor arguments for mocked classes
  • Deep MarshalByRefObject support: constructs underlying proxied object, and passes calls down to it if there are no expectations overriding them. Very useful for WinForms controls and other System.ComponentModel.Component-derived classes.

No comments:

Development Catharsis :: Copyright 2006 Mário Romano