http://blogs.clariusconsulting.net/kzu

Daniel Cazzulino's Blog

Go Back to
kzu′s Latest post

Old style imperative mocks vs moq functional specifications

Here’s a fairly complex object graph that needs to be setup as part of a unit test, as done in “traditional” moq:

    var el1 = new Mock<IElementInfo>();
    el1.Setup(x => x.Id).Returns(Guid.NewGuid());
    el1.Setup(x => x.Multiplicity).Returns(Multiplicity.Single);

    var c1 = new Mock<ICollectionInfo>();
    c1.Setup(x => x.Id).Returns(Guid.NewGuid());
    c1.Setup(x => x.Multiplicity).Returns(Multiplicity.Multiple);

    var p1 = new Mock<IPropertyInfo>();
    p1.Setup(x => x.Id).Returns(Guid.NewGuid());
    p1.Setup(x => x.Name).Returns("Foo" + Guid.NewGuid().ToString());
    p1.Setup(x => x.Type).Returns("System.String");

    var p2 = new Mock<IPropertyInfo>();
    p2.Setup(x => x.Id).Returns(Guid.NewGuid());
    p2.Setup(x => x.Name).Returns("Bar" + Guid.NewGuid().ToString());
    p2.Setup(x => x.Type).Returns("System.String");

    var elementInfoMock = new Mock<IElementInfo>();
    elementInfoMock.Setup(e => e.Id).Returns(Guid.NewGuid());
    elementInfoMock.Setup(e => e.Multiplicity).Returns(Multiplicity.Multiple);
    elementInfoMock.Setup(e => e.Elements)
        .Returns(new List<IAbstractElementInfo>
        {
            el1.Object,
            c1.Object,
        });
    elementInfoMock.Setup(x => x.Properties).Returns(
        new List<IPropertyInfo>
        {
            p1.Object,
            p2.Object,
        });

    this.elementInfo = elementInfoMock.Object;

Things to note (familiar to any moqer):

  1. Multiple temporary variables for the sole purpose of setting up intermediate mocks
  2. Setup…Returns repetitive (and boring!) pattern
  3. mock.Object annoying indirection to the mocked instance, ’cause we have to do so much to it before we’re done with it

Well, I know I got tired of all that crap. So in moq v4, you can reduce all that to a much more readable and fluent moq functional specification like this:

this.elementInfo = Mock.Of<IElementInfo>(x =>
    x.Id == Guid.NewGuid() &&
    x.Multiplicity == Multiplicity.Multiple &&
    x.Elements == new List<IAbstractElementInfo>
    {
        Mock.Of<IElementInfo>(e => e.Id == Guid.NewGuid() && e.Multiplicity == Multiplicity.Single),
        Mock.Of<ICollectionInfo>(e => e.Id == Guid.NewGuid() && e.Multiplicity == Multiplicity.Single),
    } &&
    x.Properties == new List<IPropertyInfo>
    {
        Mock.Of<IPropertyInfo>(p => p.Id == Guid.NewGuid() && p.Name == "Foo" + Guid.NewGuid() && p.Type == "System.String"),
        Mock.Of<IPropertyInfo>(p => p.Id == Guid.NewGuid() && p.Name == "Foo" + Guid.NewGuid() && p.Type == "System.String"),
    });

What you're essentially saying is "Give me a mock that behaves like this" (you also have Mocks.Of<T> if you need many). How's that for improved readability and maintainability?

 

Haven’t you become a moqer yet? ;)

Comments

8 Comments

  1. Looking really good. Just concerned for one thing. It scared the hell out of me at first…

  2. “(you also have Mocks.Of if you need many).”

    I can’t find any examples of the above when Google searching. Help?

  3. Randy: Mock.Of gives you one, Mocks.Of gives you an enumerable. Just that. The mocks you get behave just like the Mock.Of variant.

  4. Smashing! This is really lovely. Does Moq have many VB users though? Mock.Of(Of IElementInfo)

  5. what about setting up the throwing of exceptions in the mock? really like this new v4 style, but can’t figure out how to deal with exceptions.

    is there some documention about the new moq functional specifications?

  6. Throwing, callbacks, etc., you still use the traditional syntax. You can build the mock the functional way and then do Mock.Get(mock).Setup(…)

  7. [...] more @ Daniel Cazzulino’s blog. Share this:TwitterFacebookEmailPrintLike this:LikeBe the first to like this. C# Best Practices, [...]

  8. i have to post a link to here, from mine, if you dont mind, please reply, mwah