如何在我要使用 NUnit 测试的方法中模拟方法调用

本文关键字:方法 模拟 调用 测试 NUnit 我要 | 更新日期: 2023-09-27 18:31:44

我正在尝试对方法进行单元测试并模拟其中的方法调用:

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"));
    }

但这给了我一个参数例外。

我花了很多时间尝试不同的方法来完成这项工作,也尝试过 Rhino Mocks,但无法弄清楚如何模拟这个电话。谁能帮忙?我没有尝试过最小起订量,但怀疑它类似于犀牛模拟。

如何在我要使用 NUnit 测试的方法中模拟方法调用

在你目前的设置中,你试图做的事情是不可能的。需要解决的几件事:

  • 开始使用稳定版的 Rhino (如 3.6)。更好的是,升级到Moq,这是一个较新的框架
  • 使GoToMainMenu方法virtual(至少protected

你的测试(Rhino 3.6)应该看起来像这样:

var mock = MockRepository.GenerateMock<LoginViewModel>();
Assert.AreEqual(true, mock.LogUserIn("aHashedPassword"));

这里需要注意的几点。调用的任何非虚拟方法都将使用您的原始实现(如 LogUserIn )。另一方面,每个虚拟方法都将被默认(不执行任何操作)实现的 RhinoMocks 所取代,这应该足以使测试通过。最小起订量中的相同测试:

var mock = new Mock<LoginViewModel>();
Assert.AreEqual(true, mock.Object.LogUserIn("aHashedPassword"));

它的工作方式(需要有virtual方法)是因为在创建模拟时,Rhino 和 Moq 都会在内存程序集中生成并在那里创建新类型,从您的类型派生(在您的情况下,LoginViewModel )。派生类型(mock)可以替换原始类型的任何方法,因为它virtual(标准C#机制)或类型是接口 - 然后模拟只是实现接口。