2012-02-10 56 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