2009-08-02 116 views
2

其中哪些是正确的?模拟(使用moq)返回模拟对象的方法的正确方法?

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

我认为第一种方法是正确的,但我不知道,如果起订量可能引擎盖下做一些神奇的,只是想验证:)

回答

2

我猜主要问题是你想要发生的事情,如果它调用CreateTracer两次。在第一个版本中,你会得到两个不同的模拟跟踪器;在第二次你会得到同一个两次。

第二个版本是我通常在jMock,EasyMock和Rhino.Mocks中使用的 - 但是我对Moq没有任何经验,所以它可以使用或更多地方使用第一种形式。第二个更简单,虽然,国际海事组织:)

+0

我同意使用简单的第二个选项。 Nesten lambdas很难阅读。如果你想每次使用第一个选项时都需要一个新的,但是提取内部表达并给它一个好名字。 – 2009-08-02 08:32:58