[英]How to MOQ an Indexed property
我試圖模擬對索引屬性的調用。 即我想最小起訂量以下:
object result = myDictionaryCollection["SomeKeyValue"];
以及 setter 值
myDictionaryCollection["SomeKeyValue"] = myNewValue;
我這樣做是因為我需要模擬我的應用程序使用的類的功能。
有誰知道如何用 MOQ 做到這一點? 我嘗試了以下變體:
Dictionary<string, object> MyContainer = new Dictionary<string, object>();
mock.ExpectGet<object>( p => p[It.IsAny<string>()]).Returns(MyContainer[(string s)]);
但這不能編譯。
我試圖通過 MOQ 實現什么,有沒有人有我如何做到這一點的例子?
不清楚您要做什么,因為您沒有顯示模擬的聲明。 你是想嘲笑一本字典嗎?
MyContainer[(string s)]
不是有效的 C#。
這編譯:
var mock = new Mock<IDictionary>();
mock.SetupGet( p => p[It.IsAny<string>()]).Returns("foo");
Ash,如果你想模擬 HTTP Session,那么這段代碼就可以完成這項工作:
/// <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);
}
}
正如您正確發現的,有不同的方法SetupGet
和SetupSet
分別初始化 getter 和 setter。 盡管SetupGet
旨在用於屬性,而不是索引器,並且不允許您處理傳遞給它的鍵。 准確地說,對於索引器, SetupGet
無論如何都會調用Setup
:
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);
...
}
...
}
為了回答您的問題,以下是使用底層Dictionary
存儲值的代碼示例:
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);
如您所見,您必須明確指定鍵來設置索引器設置器。 詳細信息在另一個 SO 問題中描述: Moq an indexed property and use the index value in the return/callback
它不是那么難,但花了一點時間才找到它:)
var request = new Moq.Mock<HttpRequestBase>();
request.SetupGet(r => r["foo"]).Returns("bar");
看來我試圖用 MOQ 做的事情是不可能的。
本質上,我試圖對 HTTPSession 類型的對象進行 MOQ,其中設置為索引的項的鍵只能在運行時確定。 訪問需要返回先前設置的值的索引屬性。 這適用於基於整數的索引,但基於字符串的索引不起作用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.