【问题标题】:How do I mock a method call inside the method I want to test using NUnit?如何在要使用 NUnit 测试的方法中模拟方法调用?
【发布时间】:2014-11-24 22:28:56
【问题描述】:

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

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。

【问题讨论】:

  • 首先我会开始看看如何使用模拟,有很多 SO 可以帮助你,例如stackoverflow.com/questions/7394013/…。您通常模拟从一个类到另一个类的交互,而不是类内的交互。

标签: c# unit-testing mocking nunit rhino-mocks


【解决方案1】:

在您当前的设置中,您尝试执行的操作是不可能的。有几件事需要解决:

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

您的测试(Rhino 3.6)应该如下所示:

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

这里有几件事需要注意。调用的任何非虚拟方法都将使用您的原始实现(如LogUserIn)。另一方面,每个虚拟方法都将替换为具有默认 (do nothing) 实现的 RhinoMocks,这足以使测试通过。 Moq 中的相同测试:

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

它的工作方式是这样的(需要有virtual 方法)是因为在创建模拟时,Rhino 和 Moq 都会在内存组件中生成并在那里创建新类型,派生自您的类型(在您的情况下,@ 987654328@)。派生类型(模拟)然后可以替换任何原始类型的方法,给定它是 virtual(标准 C# 机制)或类型是接口 - 然后模拟简单地实现接口。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-18
    • 1970-01-01
    • 1970-01-01
    • 2013-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多