Не удается получить moq для создания экземпляра типа - "Для этого объекта не определен конструктор без параметров".

Я пытаюсь использовать Moq, чтобы заглушить класс данных, который я хочу создать динамически через Activator.CreateInstance, когда я передаю его тип (через Moq.Object.GetType(), где Moq - это экземпляр заглушки), но я получаю System.MissingMethodException {"No parameterless constructor defined for this object."}

Что я делаю неправильно? Я не хочу менять свой предметный код, чтобы приспособиться к Moq.

Тестовое задание

private Test() ...
{
   var recordStub = new Mock<IRecord>();
   var record = recordStub.Object;
   var recordDefinition = new RecordDefinition() 
                              { MappedRecordClassType = record.GetType(), ... 

   var newRecord = CreateDataRecord(recordDefinition);
   ...
}

Предмет

private IRecord CreateDataRecord(RecordDefinition recordDefinition)
{
   var result = Activator.CreateInstance(recordDefinition.MappedRecordClassType) 
                       as IRecord;
   return result;
}

3 ответа

Вы создаете экземпляр record.GetType() и с тех пор record = recordStub.Object который является объектом, динамически генерируемым Moq во время выполнения, который реализует IRecord в вашей ситуации то, что вы по существу делаете, создает экземпляр динамически генерируемого объекта, и кажется, что Activator.CreateInstance() не могу найти открытый конструктор, который не принимает аргументов для этого типа. Теперь я не знаю, почему ты делаешь то, что делаешь, но я никогда не видел, чтобы кто-нибудь использовал такую ​​насмешку, поэтому я думаю, что тебе стоит пересмотреть свой тест.

Где-то в вашем коде Moq пытается создать экземпляр объекта, который вы либо не удалили, либо выставили как класс напрямую. В любом случае у указанного объекта нет открытого конструктора, который имеет 0 параметров.

Вам нужно будет отследить, где в вашем тесте вызывается объект без открытых конструкторов 0 параметров, и либо исправить это, либо как-то иначе обойти его.

Я столкнулся с тем же самым в недавнем проекте, и в большинстве случаев мы обращались к объекту как к самому классу, а не к интерфейсу.

Я согласен с Sniffer. То, что вы делаете, проходит в typeof IRecordи затем попросите вашего Активатора создать его экземпляр. Но это интерфейс, поэтому вы не можете создать его экземпляр напрямую, вам нужен конкретный класс, чтобы сделать это.

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

Но на самом деле все, что вы делаете, это тестирование Activator.CreateInstance Я могу найти этот тип и создать его экземпляр, и я согласен с Sniffer, вы в основном тестируете сторонний код. Вы, вероятно, не должны и не должны охватывать этот метод.

Другие вопросы по тегам