2011-01-22 53 views
40

我有以下方法:使用最小起订量来嘲笑只有一些方法

public CustomObect MyMethod() 
{ 
    var lUser = GetCurrentUser(); 
    if (lUser.HaveAccess) 
    { 
     //One behavior 
    } 
    else 
    { 
     //Other behavior 
    } 

    //return CustomObject 
} 

我想嘲笑IMyInterface.GetCurrentUser,这样当调用MyMethod我能得到的代码路径之一进行检查。如何用Moq做到这一点?

我做以下的事情:

var moq = new Mock<IMyInterface>();    
moq.Setup(x => x.GetCurrentUser()).Returns(lUnauthorizedUser); 

//act 
var lResult = moq.Object.MyMethod(); 

但由于某些原因lResult总是null,当我试图进入MyMethod在调试我总是跳到下一个声明。

+0

你有什么`lUnauthorizedUser`初始化?我会想象你会想`moq.Setup(x => x.GetCurrentUser())。返回(新用户(){HaveAccess = false});` – 2011-01-22 22:30:47

+0

泰勒,当然我是在上面的代码中设置它,只是没有贴上它来保持代码简短。 – 2011-01-23 04:08:51

回答

83

这被称为部分模拟,我知道在moq中这样做需要嘲笑类而不是接口,然后将模拟对象上的“Callbase”属性设置为“true”。

这将需要使您正在测试的类的所有方法和属性变为虚拟。假设这是不是一个问题,你可以接着写这样一个测试:

var mock = new Mock<YourTestClass>(); 
mock.CallBase = true; 
mock.Setup(x => x.GetCurrentUser()).Returns(lUnauthorizedUser); 
mockedTest.Object.MyMethod(); 
+0

太棒了!非常感谢,并不认为这很简单。 – 2011-01-23 04:06:48

+0

工作就像一个魅力! – 2015-05-28 05:12:46

11

扩展在lee's answer

你不需要让所有的在你的类的虚方法和属性,只那些你想嘲笑的人。

另外,应该指出,你应该嘲笑你的课程的具体实施。

var mock = new Mock<YourTestClass>(); // vs. var mock = new Mock<IYourTestInterface>();

如果你的类没有默认构造函数,你也将需要指定的参数通过在传递给它:

var mock = new Mock<YourTestClass>(x, y, z); 
// or 
var mock = new Mock<YourTestClass>(MockBehavior.Default, x, y, z); 

x, y, z是第一,第二和第三参数分别给你的构造函数。

最后,如果你正在寻找嘲笑方法是受保护的,你将需要包括Moq.Protected

using Moq.Protected; 

TReturnType returnValue = default(TReturnType); 

mock.Protected() 
    .Setup<TReturnType>("YourMockMethodName", It.IsAny<int>()) // methodname followed by arguments 
    .Returns(returnValue); 
4

我也有类似的情况。我发现下面的代码给了我更多的灵活性,同时使用嘲笑的方法和实际方法的一些具体实施的接口:

var mock = new Mock<ITestClass>(); // Create Mock of interface 

// Create instance of ITestClass implementation you want to use 
var inst = new ActualTestClass(); 

// Setup to call method of an actual instance 
// if method returns void use mock.Setup(...).Callback(...) 
mock.Setup(m => m.SomeMethod(It.IsAny<int>()) 
    .Returns((int x) => inst.SomeMethod(x)); 

现在你可以使用实际的方法,而且使用的东西,想确认,看看有多少次它被称为。