我正在尝试对方法进行单元测试并模拟其中的方法调用:
class LoginViewModel
{
public bool LogUserIn(string hashedPassword)
{
//Code
if (loginSuccessful)
{
GoToMainMenu(); // I WANT TO MOCK THIS CALL.
return true;
}
return false;
}
}
所以我想模拟GoToMainMenu()函数调用,因为这只是用于导航,当我尝试运行测试时,我在这里抛出一个异常。
我尝试过使用NUnit.Mocks:
[Test]
public void Log_User_In_Will_Return_True()
{
DynamicMock mockView = new DynamicMock(typeof(LoginViewModel));
mockView.ExpectAndReturn("GoToMainMenu", null);
LoginViewModel loginVM = (LoginViewModel)mockView.MockInstance; //ArgumentException
Assert.AreEqual(true, loginVM.LogUserIn("aHashedPassword"));
}
但是这给了我一个ArgumentException。
我花了很多时间尝试不同的方法来完成这项工作,并且还尝试过Rhino Mocks但是无法理解如何模拟这个调用。有人能帮忙吗?我没有尝试过Moq,但怀疑它与Rhino Mocks类似。
答案 0 :(得分:1)
在您当前的设置中,您尝试做的事情是不可能的。几件事情无法解决:
GoToMainMenu
方法virtual
(至少protected
)然后你的测试(Rhino 3.6)应如下所示:
var mock = MockRepository.GenerateMock<LoginViewModel>();
Assert.AreEqual(true, mock.LogUserIn("aHashedPassword"));
这里很少有注意事项。调用的任何非虚方法都将使用您的原始实现(如LogUserIn
)。另一方面,每个虚拟方法都将被RhinoMocks替换为默认(不执行任何)实现,这应该足以使测试通过。在Moq进行相同的测试:
var mock = new Mock<LoginViewModel>();
Assert.AreEqual(true, mock.Object.LogUserIn("aHashedPassword"));
它的工作方式(需要virtual
方法)是因为在创建模拟时,Rhino和Moq都会在内存中生成程序集并在那里创建新类型,从你的类型派生(在你的情况下) ,LoginViewModel
)。派生类型(模拟)可以替换任何原始类型的方法,因为它是virtual
(标准C#机制)或类型是接口 - 然后模拟只是实现接口。