.NET Core ASP.NET Controller с сессией и тестами - PullRequest
0 голосов
/ 10 мая 2018

У меня есть свой веб-проект в .NET Core 2.x.В контроллере входа после входа в систему я сохраняю токен в Session, чтобы этот токен проходил по страницам.

Моя проблема началась, когда я захотел протестировать все контроллеры.Если я вызываю контроллер из теста, HttpContext.Session - это null.

Затем я нашел это Mock для сеанса

public class MockHttpSession : ISession
{
    Dictionary<string, object> sessionStorage = new Dictionary<string, object>();
    public object this[string name]
    {
        get { return sessionStorage[name]; }
        set { sessionStorage[name] = value; }
    }

    string ISession.Id
    {
        get {
            throw new NotImplementedException();
        }
    }
    bool ISession.IsAvailable
    {
        get {
            throw new NotImplementedException();
        }
    }
    IEnumerable<string> ISession.Keys
    {
        get { return sessionStorage.Keys; }
    }

    void ISession.Clear()
    {
        sessionStorage.Clear();
    }

    Task ISession.CommitAsync(CancellationToken cancellationToken 
                                      = default(CancellationToken))
    {
        throw new NotImplementedException();
    }

    Task ISession.LoadAsync(CancellationToken cancellationToken 
                                      = default(CancellationToken))
    {
        throw new NotImplementedException();
    }

    void ISession.Remove(string key)
    {
        sessionStorage.Remove(key);
    }

    void ISession.Set(string key, byte[] value)
    {
        sessionStorage[key] = value;
    }

    bool ISession.TryGetValue(string key, out byte[] value)
    {
        if (sessionStorage[key] != null)
        {
            value = Encoding.ASCII.GetBytes(sessionStorage[key].ToString());
            return true;
        }
        else
        {
            value = null;
            return false;
        }
    }
}

Теперь я могу получить доступ к сеансу, нодля каждого ключа мне нужно прочитать его значение, например

var sessionName = new Byte[20];
bool nameOK = HttpContext.Session.TryGetValue("name", out sessionName);
if (nameOK)
    string result = System.Text.Encoding.UTF8.GetString(sessionName);

Есть ли еще один простой способ сохранить некоторые значения для сеанса между контроллерами и тестируемым?

Обновление

Как видите, с моими фиктивными значениями в сеансе, но GetString возвращает System.Byte[] вместо значения.

With Mock With Mock: values are there

1 Ответ

0 голосов
/ 11 мая 2018

Вы можете использовать существующие ISession методы расширения, которые, вероятно, будут работать с вашей реализацией:

using Microsoft.AspNetCore.Http;

var result = HttpContext.Session.GetString("name");

Проверьте этот класс: https://github.com/aspnet/HttpAbstractions/blob/dev/src/Microsoft.AspNetCore.Http.Extensions/SessionExtensions.cs#L32

Вы также можете добавить новые дляВаши потребности

Также проверьте этот вопрос Как смоделировать объект сеанса в ядре asp net

ОБНОВЛЕНИЕ:

Похожеваш TryGetValue не совместим с методами расширения, которые будут пытаться сохранить byte [] в вашем словаре.Демон в этой строке:

value = Encoding.ASCII.GetBytes(sessionStorage[key].ToString()); Вы используете ASCII, а не UTF8, также похоже, что вы делаете двойное преобразование.

Я предлагаю изменить метод следующим образом:

bool ISession.TryGetValue(string key, out byte[] value)
{
    object storageValue = null;
    if(sessionStorage.TryGetValue(key, out storageValue))
    {
        var bytes = storageValue as byte[];

        if(bytes != null)
        {
            value = bytes;
            return true;
        }

        value = Encoding.UTF8.GetBytes(storageValue.ToString());
        return true;
    }

    value = null;
    return false;
}

Можно также подумать об использовании byte[] в качестве значения словаря, а не object

...