9

我试图为私有内部类设置单元测试,但收效甚微:

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);
      }
    }
  }
}

我试过这段代码:

PrivateType statKeyType = new PrivateType("Stats.Model", "Stats.Model.DailyStat.DailyStatKey");

PrivateType statKeyType = new PrivateType("Stats.Model", "DailyStat.DailyStatKey");

无济于事。

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

那么我做错了什么?

据我所知,PrivateType 是基于反射的,我猜它几乎适用于这种情况,因为您不能在命名空间下直接拥有私有类。

编辑:

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

4

4 回答 4

11

自己找到了解决方案:

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);
于 2010-07-08T15:01:32.843 回答
5

您也可以直接使用 PrivateType :

PrivateType statKeyType = new PrivateType("Stats.Model", "Stats.Model.DailyStat+DailyStatKey");

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

于 2014-03-27T22:51:51.900 回答
1

由于它是私有的,唯一可以创建实例的类就是DailyStat它自己。除非您将其设为非私有反射(激活器),否则如果您想创建该类,那将是您唯一的选择,尽管这不是一个好主意,因为除非您能够将其转换为足够公开,否则您将无法直接使用它类型或接口

编辑:

由于您正在尝试为单元测试执行此操作,因此您不应该有效地测试此类,因为它是私有的。您只能通过DailyStat.

于 2010-07-08T05:34:49.083 回答
-2

您可以在父类上编写公共“GetDailyStatKey”方法。

public class DailyStat
{
    private class DailyStatKey // The one to test 
    {
    }
    public DailyStatKey GetDailyStatKey()
    {
        return new  DailyStatKey();
    }
}

现在你可以写:

DailyStat v = new DailyStat();
var x =  v.GetDailyStatKey();
于 2010-07-08T05:56:26.707 回答