【问题标题】:JustMock: Mocking private MethodsJustMock:模拟私有方法
【发布时间】:2017-03-15 19:26:28
【问题描述】:

我是 JustMock 模拟框架的新手,我正在尝试模拟一个私有方法。我完全知道对私有方法进行单元测试是一种通常不好的做法,但在这种情况下,我别无选择。我一直在查看官方文档(http://www.telerik.com/help/justmock/advanced-usage-mocking-non-public-members-and-types.html),但似乎没有任何效果。

这是我的示例代码:

using System;
using Telerik.JustMock;

public class Program
{
    public class Foo
    {
        public void useA()
        {
            a();
        }

        private void a()
        {
            Console.WriteLine("AAAAAAAAAAAAAAA");
        }   
    }

    public static void Main()
    {
        var mockeClass = Mock.Create<Foo>(Behavior.CallOriginal);
        Mock.NonPublic.Arrange(mockeClass, "a").DoInstead(() => Console.WriteLine("Mock success!!!"));      

        mockeClass.useA();
    }
}

这是错误日志:

Run-time exception (line 21): The type initializer for 'Telerik.JustMock.Core.Context.MockingContext' threw an exception.

Stack Trace:

[System.Security.SecurityException: Request for the permission of type 'System.Security.Permissions.FileIOPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.]

[System.TypeInitializationException: The type initializer for 'Telerik.JustMock.Core.Context.MockingContext' threw an exception.]
  at Program.Main(): line 21

我只是很困惑为什么它不起作用。

【问题讨论】:

  • 如果您别无选择,只能显式测试私有方法,那么该方法可能不应该是私有的。考虑将方法提取到可以直接测试的自己的类中,而不是通过测试其调用者。
  • 问题是我要测试的代码结构非常糟糕。我对此无能为力。我遇到的另一种情况是私有方法返回的值会影响我正在测试的方法的逻辑。这就是为什么我需要嘲笑它。 @克里特纳

标签: c# unit-testing mocking justmock


【解决方案1】:

我尝试在一个干净的 .NET 4.5 控制台项目中运行您的代码,它按预期工作 - a() 确实打印出模拟值。 FileIOPermission 是从 JustMock 获得的一个非常不寻常的例外,可能是迄今为止第一个例外。对于控制台应用程序来说,权限错误通常更为罕见,因为它们通常在完全信任的情况下运行。

如果您将System.TypeInitializationExceptionInnerException 及其调用堆栈粘贴到票证中将会非常有帮助。只需从调试器中复制即可。

【讨论】:

    【解决方案2】:

    在我看来,有时测试有助于让我们知道如何改进我们的代码,或者应该如何构建代码,就像 Kritner 所说的那样,函数应该是公共的而不是私有的。

    另一方面,如果您想将其保持为私有,而不是测试对私有方法的调用,您可以在您的公共方法(调用私有方法的地方)中测试私有方法中的代码正在在公共方法中正确调用,私有方法不存在,代码直接写在公共方法中。

    已编辑:您甚至可以创建一个调用私有方法的简单函数(并在可能的情况下添加一些与调用相关的逻辑)并测试此函数。

    【讨论】:

    • 通过实际的单元测试,我无法编辑类。这么说吧:我在示例中的主程序相当于一个单独项目中的单元测试方法。而该课程也在一个单独的项目中。
    • 我认为您可以尝试测试该方法 useA() 正在使用 args "AAAAAAAAAAAAAAAAAA" 在类控制台中调用方法 writeLine。
    • 是的,这适用于这个例子,但是如果你必须有一定的参数值才能放入方法中,因为它会有一个复杂的算法,如果准确的话,最终会返回一个“AAAAAAAAAAAAAAAAAA”字符串。跨度>
    • 然后你创建单独的测试函数或者在nunit中使用[TestCase]来修改断言和预期结果,这样私有方法中的所有路径都被测试了。
    • 我不知道 [TestCase](谢谢)。是的,我打算为私有方法制作不同的测试方法。但坚持主要问题,我想确保私有方法更改将在调用它的公共方法中使用的值。
    猜你喜欢
    • 2014-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-03
    • 1970-01-01
    • 1970-01-01
    • 2018-07-17
    • 1970-01-01
    相关资源
    最近更新 更多