【问题标题】:Controlling private method output when unit testing单元测试时控制私有方法输出
【发布时间】:2015-07-03 16:38:54
【问题描述】:

我正在使用带有 Rhino mock 的 Nunit 测试来进行代码单元测试。我遇到过以下情况,请建议我处理这种情况。

public bool IsValidFile()
{
    ...
    ...
    if(IsValidCheksum(x, y))
    {
        ...
    }
    else
    {
        ...
    }
}

private bool IsValidCheksum(string pathTofile, string receivedChecksum)
{
}

当我对IsValidFile() 方法进行单元测试时,我想测试满足 if 条件的两种场景。但由于我无法控制IsValidCheksum 方法的输出,所以它总是返回 false。我无法测试真实情况。

有没有办法强制这个方法的返回值。

【问题讨论】:

  • 您发现了隐藏在类中的类。提取它,使其成为依赖项,模拟它。测试。

标签: c# unit-testing


【解决方案1】:

我看到了 3 种方法可以强制 IsValidCheksum 在单元测试中返回你想要的值

  1. 模拟 IsValidCheksum 中使用的一些依赖项,以便方法返回您想要的值
  2. 将 IsValidCheksum 方法设为虚拟且受保护 - 这样您就可以使用您的模拟框架对其进行模拟,如下所示:

    protected virtual bool IsValidCheksum(string pathTofile, string receivedChecksum)
    

    您也可以将 IsValidCheksum 设置为内部受保护的虚拟:

    internal protected virtual bool IsValidCheksum(string pathTofile, string receivedChecksum)
    

    并设置包含您的类的项目,以便您的单元测试项目可以看到内部结构。为此,在 AssemblyInfo.cs 文件中添加属性:

    [assembly: InternalsVisibleTo("UnitTestProjectName")]
    

    这样,您的单元测试项目将能够模拟您的方法,而对于其他项目,您的方法将保持私有。

  3. 提取 IsValidCheksum 方法以分离实现定义 IsValidCheksum 接口的类,使您的类依赖于该 iterface,并在单元测试中使用模拟接口, IsValidCheksum 返回您喜欢的任何内容。

【讨论】:

    【解决方案2】:

    你可以使用反射。

        public static object InvokeMethod(object obj, string name, object[] parameters)
        {
            var method = obj.GetType().GetMethod(name, BindingFlags.NonPublic | BindingFlags.Instance);
            return method.Invoke(obj, parameters);
        }
    

    你可以在单元测试中调用你的方法:

    [Test]
    public void TestMethod()
    {
        var test = new YourClass();
        test.IsValidFile();
        bool isValid = TestHelper.InvokeMethod(test, "IsValidCheksum", "pathTofile", "receivedChecksum");
        Assert.That(isValid, Is.True);
    }
    

    【讨论】:

      猜你喜欢
      • 2014-08-10
      • 1970-01-01
      • 2013-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-07
      相关资源
      最近更新 更多