简体   繁体   English

如何正确模拟HttpSessionStateBase中的KeysCollection?

[英]How can I properly Mock the KeysCollection in HttpSessionStateBase?

I setup this mock session object from the example here: How to MOQ an Indexed property 我从这里的示例中设置了这个模拟会话对象: 如何最小化一个索引属性

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

some sample code to produce an error... 一些示例代码会产生错误...

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

Error: The method or operation is not implemented. 错误: 该方法或操作未实现。

I need to implement the Keys property, but can't create a KeysCollection object. 我需要实现Keys属性,但是不能创建KeysCollection对象。

What is the best way to do this? 做这个的最好方式是什么?

EDIT: [SOLUTION] 编辑:[解决方案]

I ended up changing the HttpSessionMock based on the answer given. 我最终根据给出的答案更改了HttpSessionMock。 This is what I ended up with. 这就是我最后得到的。 (I also added a reference to System.Linq). (我还添加了对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; }
    }
}

note: this mock session will only store strings, not objects. 注意:此模拟会话将仅存储字符串,而不存储对象。

I found a combination of the original approach and the accepted solution allows both storing of objects and implementing the keys property: 我发现原始方法和公认的解决方案相结合,既可以存储对象又可以实现keys属性:

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

One way: 单程:

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

    private readonly NameValueCollection _collection = new NameValueCollection();
}

Updated: For your reference, below is the source code of KeysCollection from .NET framework: 更新:供您参考,以下是.NET Framework中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;
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM