Имитация метода интерфейса, который возвращает структуру только для чтения - PullRequest
0 голосов
/ 03 августа 2020

Я пытаюсь имитировать метод интерфейса, который возвращает структуру только для чтения с внутренним конструктором. Поскольку мне нужно, чтобы в моем поддельном ответе были определенные значения в объекте, как этого добиться? Я использую XUnit и Moq.

Рабочий пример с использованием библиотеки обмена стеками redis; Этот интерфейс IDatabase имеет метод StreamGroupInfo, а объект ответа - StreamGroupInfo . Этот объект ответа является структурой только для чтения с внутренним конструктором, поэтому я не могу просто создать экземпляр объекта и назначить желаемые значения.

1 Ответ

1 голос
/ 03 августа 2020

Вы можете использовать Activator.CreateInstance

// Arguments to pass to internal constructor here in order
var args = new object[] { "name", 10, 20, "someId" };
// You need to leave the (Binder) and (CultureInfo) casts so that C# compiler would call the correct overload for Activator.CreateInstance
var obj = (StreamGroupInfo)Activator.CreateInstance(typeof(StreamGroupInfo), BindingFlags.NonPublic | BindingFlags.Instance, (Binder)null, args, (CultureInfo)null);

Обратите внимание, что в приведенном выше коде есть два приведения типов, которые кажутся ненужными (и Visual Studio порекомендует вам удалить их). Но поскольку значение параметров равно нулю, C# не может узнать типы параметров. Таким образом, он примет тип Object и вызовет перегрузку Activator.CreateInstance (Type type, params object [] args), которая не будет работать. Вы можете переписать код следующим образом, чтобы Visual Studio не рекомендовала вам удалить приведение типов, и это всего лишь две дополнительные строки / переменные.

// Arguments to pass to internal constructor here in order
var args = new object[] { "name", 10, 20, "someId" };
Binder binder = null;
CultureInfo culture = null;
var obj = (StreamGroupInfo)Activator.CreateInstance(typeof(StreamGroupInfo), BindingFlags.NonPublic | BindingFlags.Instance, binder, args, culture);
...