views:

411

answers:

1

Which of these is correct?

var mockLogger = new Mock<EntLibLogger>();
mockLogger.Setup(i => i.CreateTracer(It.IsAny<string>()))
    .Returns((string operationName) =>
        {
            var mockTracer = new Mock<EntLibTracer>(operationName);
            mockTracer.Setup(i => i.IsTracingEnabled())
                .Returns(true);
            mockTracer.CallBase = true;

            return mockTracer.Object;
        });
mockLogger.CallBase = true;

//EntLibLogger.Current is a singleton that is shared across multiple threads.
//This Initialize method will set EntLibLogger.Current to the mocked instance
//instead of the default (non-mocked) configuration
EntLibLogger.Initialize(mockLogger.Object);

OR

var mockTracer = new Mock<EntLibTracer>(operationName);
mockTracer.Setup(i => i.IsTracingEnabled())
    .Returns(true);
mockTracer.CallBase = true;

var mockLogger = new Mock<EntLibLogger>();
mockLogger.Setup(i => i.CreateTracer(It.IsAny<string>()))
    .Returns(mockTracer.Object);
mockLogger.CallBase = true;

EntLibLogger.Initialize(mockLogger.Object);

I believe the first approach is correct but I am not sure if Moq might be doing some magic under the hood and just wanted to validate :)

+2  A: 

I guess the main question is what you want to happen if it calls CreateTracer twice. In the first version you'll get two different mock tracers; in the second you'll get the same one twice.

The second version is what I've usually used in jMock, EasyMock and Rhino.Mocks - but I don't have any experience with Moq, so it may be more idiomatic to use the first form there. The second is simpler though, IMO :)

Jon Skeet
I agree with using the second option for the simplicity. Nesten lambdas are hard to read. If you want a new one each time you could use the first option, but extract the inner expression and give it a good name.
Torbjørn