Ich versuche, mithilfe der Moq-Bibliothek eine Nachbildung der Schnittstelle ISomeService zu erstellen, die ihre eigentliche Implementierung SomeService umschließt< /code>.
Im Moment mache ich das manuell so:
Code: Select all
var instance = new SomeService();
var mock = new Mock();
mock.Setup(x => x.Run(It.IsAny()))
.Returns(x => instance.Run(x));
WAS ICH GEMACHT HABE
Was ich für Setup() habe Teil ist
Code: Select all
// (x)
var mockParameter = Expression.Parameter(typeof(T), "x");
// It.IsAny()
var isAnyMethod = typeof(It).GetMethod(nameof(It.IsAny));
var isAny = parameters.Select(x => Expression.Call(isAnyMethod.MakeGenericMethod(x.ParameterType))).ToArray();
// x.Run(It.IsAny())
mockCall = Expression.Call(mockParameter, method, isAny);
Code: Select all
// (x) => x.Run(It.IsAny())
var mockLambda = Expression.Lambda(mockCall, mockParameter);
Code: Select all
public ISetup Setup(Expression expression)
Code: Select all
var setupMethod = typeof(Mock)
.GetMethods()
.Where(x => x.Name == nameof(mock.Setup) && x.GetParameters()[0].ParameterType.GetGenericArguments()[0].GetGenericTypeDefinition() == typeof(Func)).First()
.MakeGenericMethod(method.ReturnType);
var setupResult = setupMethod.Invoke(mock, new object[] { mockLambda });
System.InvalidOperationException: „Spät gebundene Vorgänge können nicht für Typen oder Methoden ausgeführt werden.“ which ContainsGenericParameters is true.'
was Sinn macht, aber enttäuschend ist.
WAS ICH VERSUCHT HABE< /strong>
Ich habe versucht, das Ergebnis zu übertragen Typ zu Objekt Typ
Code: Select all
var converted = Expression.Convert(mockCall, typeof(object));
Code: Select all
// (x) => (object)x.Run(It.IsAny())
var mockLambda = Expression.Lambda(converted, mockParameter);
System.ArgumentException: 'Unsupported expression: (object)x.Run( It.IsAny())'
Damit dies funktioniert, habe ich eine Reihe von else if-Anweisungen für Werttypen hinzugefügt, bei denen ich für einen bestimmten Ergebnistyp einen bestimmten Ausdruck zurückgebe aber das Es ist ein Albtraum, es aufrechtzuerhalten und zu erweitern. Für Klassen verwende ich Objekt und zumindest dieser Teil funktioniert.
Für benutzerdefinierte Werttypen habe ich eine generische Methode hinzugefügt
Code: Select all
void SetupUnsuportedMethod(MethodInfo methodInfo)
FRAGE[/b]
Gibt es eine Möglichkeit, diesen Code vollständig generisch zu gestalten? Vielleicht gibt es einen besseren Weg, dieses Problem zu lösen? Oder muss ich mich an diese fiese Sonst-wenn-Lösung halten?