簡體   English   中英

如何最小起訂量索引屬性

[英]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);
    }
}

正如您正確發現的,有不同的方法SetupGetSetupSet分別初始化 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM