【问题标题】:Setting a property within a class that has an internal setter for use in testing (C#)在具有用于测试的内部设置器的类中设置属性(C#)
【发布时间】:2018-11-30 10:43:43
【问题描述】:

我正在使用 NJsonSchema 来验证 JSON 输入。

我有一个小类,它采用ValidationError 对象的集合,并使用每个验证错误的内容创建更多用户友好的错误消息。

我希望能够为这个类编写单元测试,但是我遇到了一个问题。我的班级中的一个消息处理程序负责处理 NotInEnumeration 错误,为此它使用 ValidationError 中保存的 JsonSchema4 对象中的 Enumeration 属性并创建格式正确的错误消息。

在为这个特定的处理程序编写测试时,我发现以下内容是非法的:

JsonSchema4 enumSchema = new JsonSchema4();
enumSchema.Enumeration = new List<object>{ "A", "B", "C" };

这是因为 Enumeration 属性有一个内部设置器。

我需要能够设置验证错误的枚举,因为对象需要传递给 ValidationError 的构造函数,然后由我的处理程序稍后读取,如下所示。

private string NotInEnumerationHandler(ValidationError error)
        {
            var userFriendlyErrorString = "Answer must be within range: ";
            var enumString = "[" + string.Join<object>(", ", error.Schema.Enumeration) + "]";
            userFriendlyErrorString += enumString;
            return userFriendlyErrorString;
        }

我无法使用 moq 模拟 JsonSchema4 对象,因为 moq 不允许模拟非虚拟方法。

基本上细节并不重要,但我想知道是否有任何方法可以设置内部设置器,以便我可以在我的类中测试这个特定方法。

【问题讨论】:

  • 您可以使用AssemblyInfo.cs 中的InternalsVisibleTo-属性使您的测试程序集成为您正在测试的系统的朋友项目。这样您也应该能够访问内部设置器。
  • 枚举是一个ICollection。为什么不简单地 Add() 你需要的项目?
  • @IvayloStoev 你知道什么时候只见树木不见森林吗?
  • 一直发生在我身上:-)

标签: c# njsonschema


【解决方案1】:

JsonSchema4.Enumeration 是一个ICollection&lt;Object&gt;

因此,我不需要将Enumeration 的值设置为新集合,只需将我想要的项目添加到现有集合中即可。

【讨论】:

    【解决方案2】:

    可以使用反射来设置,首先需要获取属性的属性信息,然后将值设置为你创建的实例。

    var enumSchema = new JsonSchema4();
    var propertyInfo = typeof(JsonSchema4).GetProperty("Enumeration", BindingFlags.Public | BindingFlags.Instance);
    propertyInfo.SetValue(enumSchema, new List<object> { "A", "B", "C" });
    

    这就是您可以验证它是否有效的方法

    Console.WriteLine(propertyInfo.GetValue(enumSchema, null));
    

    您可以制作一些扩展方法来为您的测试程序集提供“枚举”属性。

    【讨论】:

      【解决方案3】:

      这不是一个完整的答案,我只是发表了太多评论,而且它的格式也不正确。 下面是您的 AssemblyInfo.cs 的示例:

      using System.Reflection;
      using System.Runtime.CompilerServices;
      
      [assembly: AssemblyTitle("Assembly.Fully.Qualified.Name")]
      [assembly: AssemblyDescription("")]
      
      #if DEBUG
      [assembly: InternalsVisibleTo("Assembly.Fully.Qualified.Name")]
      [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
      #endif
      

      您需要两个属性的底部 DynamicProxyGenAssembly2 以便 Moq 能够看到内部结构。您可能不需要 Debug 和 Release 开关,在这种情况下不要打扰 #if DEBUG 部分。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-24
        • 1970-01-01
        • 1970-01-01
        • 2016-11-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多