Правильный способ имитации (с moq) методов, которые возвращают смоделированные объекты? - PullRequest
2 голосов
/ 02 августа 2009

Что из этого является правильным?

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);

Я полагаю, что первый подход верен, но я не уверен, что Мок может творить магию под капотом, и просто хотел проверить:)

1 Ответ

2 голосов
/ 02 августа 2009

Полагаю, главный вопрос в том, что вы хотите, чтобы он вызывал CreateTracer дважды. В первой версии вы получите два разных макета; во втором вы получите один и тот же дважды.

Вторая версия - это то, что я обычно использовал в jMock, EasyMock и Rhino.Mocks - но у меня нет опыта работы с Moq, поэтому может быть более идиоматичным в использовании первой формы там. Второй проще, хотя, ИМО:)

...