2011-08-09 70 views
7

我設置從這裏的示例中,這模擬會話對象:How to MOQ an Indexed property如何正確模擬HttpSessionStateBase中的KeysCollection?

/// <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; } 
    } 
} 

一些示例代碼,以產生誤差...

var mockSession = new HttpSessionMock(); 
var keys = mockSession.Keys; 

錯誤:的方法或操作未實現。

我需要實現Keys屬性,但不能創建KeysCollection對象。

這樣做的最好方法是什麼?

編輯:[解決方法]

我最終改變基礎上給出了答案HttpSessionMock。這是我結束了。 (我還添加了對System.Linq的引用)。

internal sealed class HttpSessionMock : HttpSessionStateBase 
{ 
    private readonly NameValueCollection objects = new NameValueCollection(); 

    public override object this[string name] 
    { 
     get { return (objects.AllKeys.Contains(name)) ? objects[name] : null; } 
     set { objects[name] = (string)value; } 
    } 

    public override NameObjectCollectionBase.KeysCollection Keys 
    { 
     get { return objects.Keys; } 
    } 
} 

注意:這個模擬會話將只存儲字符串,而不是對象。

+0

雖然代碼來自Moq問題,但該解決方案不使用Moq庫。我建議刪除Moq標籤。 – TrueWill

+0

Moq標籤已移除。 – joelnet

+0

當我嘗試將bool放入其中時,這個模擬/假冒事件爆炸了。我發現了一個適用於此的代碼片段:http://stackoverflow.com/questions/524457/how-do-you-mock-the-session-object-collection-using-moq – 2012-04-02 18:21:26

回答

15

我發現原來的方法和組合接受的解決方案允許存儲對象和實現密鑰屬性:

public class HttpSessionMock : HttpSessionStateBase 
{ 
    private readonly NameValueCollection keyCollection = new NameValueCollection(); 
    private readonly Dictionary<string, object> objects = new Dictionary<string, object>(); 

    public override object this[string name] 
    { 
     get 
     { 
      object result = null; 

      if (objects.ContainsKey(name)) 
      { 
       result = objects[name]; 
      } 

      return result; 

     } 
     set 
     { 
      objects[name] = value; 
      keyCollection[name] = null; 
     } 
    } 

    public override NameObjectCollectionBase.KeysCollection Keys 
    { 
     get { return keyCollection.Keys; } 
    } 
} 
0

更新時間: 供您參考,以下是從.NET框架KeysCollection的源代碼:

public class KeysCollection : ICollection, IEnumerable 
{ 
    // Fields 
    private NameObjectCollectionBase _coll; 

    // Methods 
    internal KeysCollection(NameObjectCollectionBase coll) 
    { 
     this._coll = coll; 
    } 

    public virtual string Get(int index) 
    { 
     return this._coll.BaseGetKey(index); 
    } 

    public IEnumerator GetEnumerator() 
    { 
     return new NameObjectCollectionBase.NameObjectKeysEnumerator(this._coll); 
    } 

    void ICollection.CopyTo(Array array, int index) 
    { 
     if (array == null) 
     { 
      throw new ArgumentNullException("array"); 
     } 
     if (array.Rank != 1) 
     { 
      throw new ArgumentException(SR.GetString("Arg_MultiRank")); 
     } 
     if (index < 0) 
     { 
      throw new ArgumentOutOfRangeException("index", SR.GetString("IndexOutOfRange", new object[] { index.ToString(CultureInfo.CurrentCulture) })); 
     } 
     if ((array.Length - index) < this._coll.Count) 
     { 
      throw new ArgumentException(SR.GetString("Arg_InsufficientSpace")); 
     } 
     IEnumerator enumerator = this.GetEnumerator(); 
     while (enumerator.MoveNext()) 
     { 
      array.SetValue(enumerator.Current, index++); 
     } 
    } 

    // Properties 
    public int Count 
    { 
     get 
     { 
      return this._coll.Count; 
     } 
    } 

    public string this[int index] 
    { 
     get 
     { 
      return this.Get(index); 
     } 
    } 

    bool ICollection.IsSynchronized 
    { 
     get 
     { 
      return false; 
     } 
    } 

    object ICollection.SyncRoot 
    { 
     get 
     { 
      return ((ICollection) this._coll).SyncRoot; 
     } 
    } 
} 
+0

objects.Keys is type Dictionary < TKey,TValue> .KeyCollection和HttpSessionStateBase是NameObjectCollectionBase.KeysCollection類型,所以我無法映射到objects.Keys。 – joelnet

+0

抱歉沒有注意到。但是,您可以從NameObjectCollectionBase.KeysCollection繼承一個新類,實現您自己的邏輯,當鍵/值對添加到字典中時,可以對KeysCollection進行必要的更改。希望這可以幫助。 – gekowa

+0

我也嘗試繼承這個類,但是在創建我自己的公共構造函數時收到了這個錯誤信息「錯誤類型'System.Collections.Specialized.NameObjectCollectionBase.KeysCollection'沒有定義構造函數」 – joelnet

4

方式一:

internal sealed class HttpSessionMock : HttpSessionStateBase 
{ 
    public override NameObjectCollectionBase.KeysCollection Keys 
    { 
     get { return _collection.Keys; } 
    } 

    private readonly NameValueCollection _collection = new NameValueCollection(); 
} 
+0

啊hhh。這是如何完成的。謝謝你,先生。 – joelnet

+1

這不適合我,scdove的答案完美無缺。 –