如何实例化内部私有类的PrivateType

Ste*_*fen 9 c# unit-testing private-members

我试图为私人内部课程设置单元测试,但收效甚微:

namespace Stats.Model
{
  public class DailyStat
  {
    private class DailyStatKey // The one to test
    {
      private DateTime date;
      public DateTime Date 
      { 
        get { return date; }
        set { date = value.Date; }
      }

      public StatType Type { get; set; }

      public override int GetHashCode()
      {
        return Date.Year * 1000000 +
               Date.Month * 10000 +
               Date.Day * 100 +
               (int)Type;
      }

      public override bool Equals(object obj)
      {
        DailyStatKey otherKey = obj as DailyStatKey;
        if (otherKey == null)
          return false;
        return (this.Date == otherKey.Date && this.StatType == otherKey.StatType);
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

我试过这段代码:

PrivateType statKeyType = new PrivateType("Stats.Model", "Stats.Model.DailyStat.DailyStatKey");
Run Code Online (Sandbox Code Playgroud)

以及

PrivateType statKeyType = new PrivateType("Stats.Model", "DailyStat.DailyStatKey");
Run Code Online (Sandbox Code Playgroud)

无济于事.

程序集的名称是"Stats.Model",对我来说类型名称看起来也是正确的,但我只是得到一个异常:"System.TypeLoadException:无法加载类型"

那么我做错了什么?

据我所知,PrivateType是基于反射的,我猜它几乎是针对这种情况的,因为你不能直接在命名空间下面有一个私有类.

编辑:

添加了DailyStatKey的完整实现.我想测试的是我的GetHashCode方法的唯一性.正如您所看到的,我尝试将日期+类型放入单个int中.

Ste*_*fen 9

自己找到了解决方案:

var parentType = typeof(DailyStat);
var keyType = parentType.GetNestedType("DailyKeyStat", BindingFlags.NonPublic); 
//edited to use GetNestedType instead of just NestedType

var privateKeyInstance = new PrivateObject(Activator.CreateInstance(keyType, true));

privateKeyInstance.SetProperty("Date", DateTime.Now);
privateKeyInstance.SetProperty("Type", StatType.Foo);

var hashCode = (int)privateKeyInstance.Invoke("GetHashCode", null);
Run Code Online (Sandbox Code Playgroud)


Jak*_*ake 5

您也可以直接使用PrivateType:

PrivateType statKeyType = new PrivateType("Stats.Model", "Stats.Model.DailyStat+DailyStatKey");
Run Code Online (Sandbox Code Playgroud)

嵌套类具有与其命名空间不同的字符串格式(即Stats.Model.DailyStat.DailyStatKey),因此用法不明显.