2010-11-03 48 views
2

有沒有辦法使用字符串參數而不是表達式設置Moq模擬器?您可以使用受保護函數的受保護擴展來執行此操作,但如果公用則拋出異常。例如,這裏是你如何可能設置與一個Moq的保護無效的功能:用字符串設置Moq的函數

myMock.Protected().Setup("MyProtectedFunction"); 

我希望能夠做同樣的事情與公共功能。如果我能做到這一點,我已經有了一些反射代碼,可以返回我需要模擬的所有函數的名稱,並且我希望能夠在此基礎上進行構建,以避免必須在龐大的工廠類上設置許多功能。

回答

3

有趣的問題,這幾乎可以做到使用表達式。由於setup方法需要一個表達式,因此可以在運行時構建它。

需要在編譯時發生的唯一一點是根據模擬方法的返回類型將表達式轉換爲適當的lambda類型。不幸的是,Moq沒有提供Setup超負荷運行Expression,否則它可能會在運行時做到100%。

public abstract class Fruit 
{ 
} 

public class Apple :Fruit 
{ 
} 

public interface IFactory { 
    Fruit CreateFruit(string type); 
    void VoidMethod(int intParameter); 
} 

[TestClass] 
public class UnitTest1 { 
    [TestMethod] 
    public void TestMethod1() { 
     var factoryMock = new Mock<IFactory>(); 

     Expression factoryCall = Expression.Lambda(
      Expression.Call(Expression.Variable(typeof(IFactory), "f"), "CreateFruit", new Type[]{}, Expression.Constant("Apple")), 
      Expression.Parameter(typeof(IFactory), "f")); 

     //factoryMock.Setup(f=>f.CreateFruit("Apple")).Returns(new Apple()); 

     factoryMock.Setup((Expression<Func<IFactory, Fruit>>)factoryCall).Returns(new Apple()); 
     var ret = factoryMock.Object.CreateFruit("Apple"); 
     Assert.IsInstanceOfType(ret, typeof(Apple)); 
    } 
} 
+0

謝謝,有一些調整,這對我做了。 – 2010-11-04 17:53:07

+0

你有沒有機會寫出你如何解決整個問題?我正在嘗試做類似的事情。 – 2011-06-23 21:12:35

+0

你好,你認爲你可以提供這樣的代碼,但建立屬性,而不是方法? 謝謝 – 2017-10-21 19:06:18