Ich versuche, einen Aufruf einer indizierten Eigenschaft zu verspotten. Dh ich möchte folgendes moq:
object result = myDictionaryCollection["SomeKeyValue"];
und auch den Setterwert
myDictionaryCollection["SomeKeyValue"] = myNewValue;
Ich mache das, weil ich die Funktionalität einer Klasse verspotten muss, die meine App verwendet.
Weiß jemand, wie man das mit MOQ macht? Ich habe folgende Variationen ausprobiert:
Dictionary<string, object> MyContainer = new Dictionary<string, object>();
mock.ExpectGet<object>( p => p[It.IsAny<string>()]).Returns(MyContainer[(string s)]);
Das lässt sich aber nicht kompilieren.
Ist das, was ich mit MOQ erreichen möchte, möglich? Hat jemand Beispiele dafür, wie ich das tun kann?
Antworten:
Es ist nicht klar, was Sie versuchen, weil Sie die Erklärung des Scheines nicht zeigen. Versuchen Sie, ein Wörterbuch zu verspotten?
MyContainer[(string s)]
ist nicht gültig C #.Dies kompiliert:
var mock = new Mock<IDictionary>(); mock.SetupGet( p => p[It.IsAny<string>()]).Returns("foo");
quelle
SetupSet
anstelle vonExpectGet
. funktioniert auch für Setter.Ash, wenn Sie einen HTTP-Sitzungs-Mock haben möchten, dann erledigt dieser Code den Job:
/// <summary> /// HTTP session mockup. /// </summary> internal sealed class HttpSessionMock : HttpSessionStateBase { private readonly Dictionary<string, object> objects = new Dictionary<string, object>(); public override object this[string name] { get { return (objects.ContainsKey(name)) ? objects[name] : null; } set { objects[name] = value; } } } /// <summary> /// Base class for all controller tests. /// </summary> public class ControllerTestSuiteBase : TestSuiteBase { private readonly HttpSessionMock sessionMock = new HttpSessionMock(); protected readonly Mock<HttpContextBase> Context = new Mock<HttpContextBase>(); protected readonly Mock<HttpSessionStateBase> Session = new Mock<HttpSessionStateBase>(); public ControllerTestSuiteBase() : base() { Context.Expect(ctx => ctx.Session).Returns(sessionMock); } }
quelle
TestSuiteBase
eine Bibliothek oder Ihre eigene Klasse?Wie Sie richtig entdeckt, gibt es verschiedene Methoden
SetupGet
undSetupSet
jeweils Getter und Setter zu initialisieren. ObwohlSetupGet
für Eigenschaften und nicht für Indexer vorgesehen ist und Sie keine an ihn übergebenen Schlüssel verarbeiten können. Um genau zu sein, werden Indexer trotzdemSetupGet
anrufenSetup
:internal static MethodCallReturn<T, TProperty> SetupGet<T, TProperty>(Mock<T> mock, Expression<Func<T, TProperty>> expression, Condition condition) where T : class { return PexProtector.Invoke<MethodCallReturn<T, TProperty>>((Func<MethodCallReturn<T, TProperty>>) (() => { if (ExpressionExtensions.IsPropertyIndexer((LambdaExpression) expression)) return Mock.Setup<T, TProperty>(mock, expression, condition); ... } ... }
Um Ihre Frage zu beantworten, finden Sie hier ein Codebeispiel mit dem zugrunde liegenden
Dictionary
Wert zum Speichern von Werten:var dictionary = new Dictionary<string, object>(); var applicationSettingsBaseMock = new Mock<SettingsBase>(); applicationSettingsBaseMock .Setup(sb => sb[It.IsAny<string>()]) .Returns((string key) => dictionary[key]); applicationSettingsBaseMock .SetupSet(sb => sb["Expected Key"] = It.IsAny<object>()) .Callback((string key, object value) => dictionary[key] = value);
Wie Sie sehen können, müssen Sie den Schlüssel explizit angeben, um den Indexer-Setter einzurichten. Details werden in einer anderen SO-Frage beschrieben: Moq eine indizierte Eigenschaft und verwenden Sie den Indexwert in der Rückgabe / Rückruf
quelle
Es ist nicht so schwierig, aber es hat ein bisschen gedauert, es zu finden :)
var request = new Moq.Mock<HttpRequestBase>(); request.SetupGet(r => r["foo"]).Returns("bar");
quelle
Es scheint, dass das, was ich mit MOQ versucht habe, nicht möglich ist.
Im Wesentlichen habe ich versucht, ein Objekt vom Typ HTTPSession zu MOQ, bei dem der Schlüssel des Elements, das auf den Index gesetzt wird, nur zur Laufzeit ermittelt werden konnte. Zugriff auf die indizierte Eigenschaft, die erforderlich ist, um den zuvor festgelegten Wert zurückzugeben. Dies funktioniert für ganzzahlige Indizes, aber stringbasierte Indizes funktionieren nicht.
quelle