2012-02-10 55 views
1

我很滿意Moq,直到我需要測試一個以委託爲參數並且有UnsupportedException的方法。該問題也被提及here和Moq issue list模擬框架,支持以委託爲參數嘲諷方法

有沒有支持這種嘲諷的框架?

例如:

/// 
/// Interfaces 
/// 

public interface IChannelFactory<T> { 
    TReturn UseService<TReturn>(Func<T, TReturn> function); 
} 

public interface IService { 
    int Calculate(int i); 
} 

/// 
/// Test 
/// 

Mock<IChannelFactory<IService>> mock = new Mock<IChannelFactory<IService>>(); 

// This line results in UnsupportedException 
mock.Setup(x => x.UseService(service => service.Calculate(It.IsAny<int>()))).Returns(10); 
+0

這是實際的代碼,還是隻是一些樣本片段?我問,因爲它看起來沒有完全指定。例如,當你創建你的模擬,那裏不應該有另一個泛型的層次? '新模擬>'? – 2012-02-10 18:40:06

+0

啊,是的,謝謝你的更正。這不是複製粘貼,因此是錯誤。 – henginy 2012-02-10 23:14:51

+0

在設置行中,您傳遞一個表達式(service => service.Calculate())。你需要傳遞一些解析到委託的東西,例如Func <>對象。 – IanNorton 2012-02-11 07:17:44

回答

3

我不太清楚你想要做什麼,但這種編譯和使用接口與起訂量運行4:

var mock = new Mock<IChannelFactory<IService>>(); 

mock.Setup(x => x.UseService(It.IsAny<Func<IService, int>>())).Returns(10); 

int result = mock.Object.UseService(x => 0); 

Console.WriteLine(result); // prints 10 

this answer見一個更復雜的情況下, 。

+0

謝謝,但是這個將爲UseService中的任何方法調用設置模擬,而我試圖選擇一個特定的方法。我將盡快檢查鏈接中的答案。 – henginy 2012-02-13 07:48:01

+0

鏈接的答案可能會讓你得到你想要的。我會告誡你一次只想測試一件事情,這通常意味着保持你的模擬和存根的簡單。你做得越複雜,測試你的模擬得越多。 – TrueWill 2012-02-13 14:20:43

0

看一看痣。它支持代表作爲嘲笑。

Moles

1

最近我遇到了這個問題,下面介紹如何使用moq(v4.0.10827)來測試正確的方法和參數。 (提示:你需要兩層模擬。)

//setup test input 
int testInput = 1; 
int someOutput = 10; 

//Setup the service to expect a specific call with specific input 
//output is irrelevant, because we won't be comparing it to anything 
Mock<IService> mockService = new Mock<IService>(MockBehavior.Strict); 
mockService.Setup(x => x.Calculate(testInput)).Returns(someOutput).Verifiable(); 

//Setup the factory to pass requests through to our mocked IService 
//This uses a lambda expression in the return statement to call whatever delegate you provide on the IService mock 
Mock<IChannelFactory<IService>> mockFactory = new Mock<IChannelFactory<IService>>(MockBehavior.Strict); 
mockFactory.Setup(x => x.UseService(It.IsAny<Func<IService, int>>())).Returns((Func<IService, int> serviceCall) => serviceCall(mockService.Object)).Verifiable(); 

//Instantiate the object you're testing, and pass in the IChannelFactory 
//then call whatever method that's being covered by the test 
// 
//var target = new object(mockFactory.Object); 
//target.targetMethod(testInput); 

//verifying the mocks is all that's needed for this unit test 
//unless the value returned by the IService method is used for something 
mockFactory.Verify(); 
mockService.Verify(); 
+0

這很有趣!謝謝,我會嘗試它。 – henginy 2013-01-21 09:51:25