Как инстанцировать PrivateType внутреннего частного класса

Я пытался установить модульный тест на частный внутренний класс, но имел очень мало успеха:

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

Напрасно.

Именем блока является "Статистика. Модель", и мне, имя типа выглядит корректным также, но я просто получаю исключение: "Система. TypeLoadException: не Мог загрузить тип"

Таким образом, что я делаю неправильно?

PrivateType, насколько я знаю, является отражением, базирующимся, и я предположил бы, что он в значительной степени предназначается для этого сценария, поскольку у Вас не может быть частного класса непосредственно под пространством имен.

Править:

Добавленное полное внедрение DailyStatKey. То, что я хочу протестировать, является уникальностью моего метода GetHashCode. Поскольку Вы видите, что я пытаюсь соответствовать дате + тип в единственный интервал.

9
задан Steffen 8 July 2010 в 06:25
поделиться

3 ответа

Я сам нашел решение:

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);
9
ответ дан 4 December 2019 в 15:11
поделиться

Поскольку он является частным, единственный класс, который может создать экземпляр, это DailyStat. Если вы не сделаете его неприватным, отражение (активатор) будет вашим единственным выбором, если вы хотите создать класс, хотя это не очень хорошая идея, так как вы не сможете использовать его напрямую, если не сможете привести его к достаточно публичному типу или интерфейсу

EDIT:

Поскольку вы пытаетесь сделать это для модульного тестирования, то фактически вы не должны тестировать этот класс, так как он приватный. Вы сможете протестировать его только через любой публичный интерфейс DailyStat.

1
ответ дан 4 December 2019 в 15:11
поделиться

Вы можете закодировать общедоступный метод 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();
-2
ответ дан 4 December 2019 в 15:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: