开发者

How to instantiate PrivateType of inner private class

I was trying to setup a unit test for a private inner class, but had very little success:

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.Dat开发者_如何学Goe; }
      }

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

I tried this code:

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

as well as

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

To no avail.

The assembly's name is "Stats.Model", and to me the type name looks correct too, but I just get an exception: "System.TypeLoadException: Could not load type"

So what am I doing wrong ?

PrivateType, to the best of my knowledge, is reflection based, and I'd guess it's pretty much intended for this scenario, as you cannot have a private class directly beneath a namespace.

EDIT:

Added full implementation of DailyStatKey. What I want to test is the uniqueness of my GetHashCode method. As you can see I try to fit a date + type into a single int.


Found a solution myself:

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


You can also use PrivateType directly as well:

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

Nested classes have a string format that's different from their namespace (which is Stats.Model.DailyStat.DailyStatKey) so the usage isn't obvious.


Since it is private the only class that can create the instance is DailyStat itself. Unless you make it non private reflection (activator) would be your only choice if you want to create the class although that would not be a good idea as you wont be able to use it directly unless you are able to cast it to a public enough type or interface

EDIT:

Since you are trying to do this for unit testing then effectively you shouldnt test this class as it is private. You would only be able to test it through any public interface of DailyStat.


You can code a public "GetDailyStatKey" method on parent class.

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

Now you can write:

DailyStat v = new DailyStat();
var x =  v.GetDailyStatKey();
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜