Это правильный способ издеваться над HttpContextBase, HttpRequestBase и HttpResponseBase для модульного тестирования файлов cookie?

1

Учитывая следующий класс для написания и чтения файлов cookie:

public static class CookieManager
{
    #region Methods

    /// <summary>
    ///     Writes a new cookie on the.
    /// </summary>
    /// <param name="response">The <see cref="HttpResponseBase"/> that is used to write the cookies.</param>
    /// <param name="name">The name of the cookie.</param>
    /// <param name="value">The value of the cookie.</param>
    public static void Write(HttpResponseBase response, string name, string value)
    {
        var applicationCookie = new HttpCookie(name) { Value = value, Expires = DateTime.Now.AddYears(1) };
        response.Cookies.Add(applicationCookie);
    }

    /// <summary>
    ///     Reads a cookie.
    /// </summary>
    /// <param name="request">The <see cref="HttpRequestBase"/> that is used to read cookies.</param>
    /// <param name="name">The name of the cookie to read.</param>
    /// <param name="defaultValue">The value to return when the cookie does not exists.</param>
    /// <returns>The value of the cookie if it exists, otherwise the defautValue.</returns>
    public static string Read(HttpRequestBase request, string name, string defaultValue)
    {
        if (request.Cookies[name] != null)
        {
            return request.Cookies[name].Value;
        }

        return defaultValue;
    }

    /// <summary>
    ///     Check if a cookie does exists.
    /// </summary>
    /// <param name="request">The <see cref="HttpRequestBase"/> that is used to read cookies.</param>
    /// <param name="name">The name of the cookie.</param>
    /// <returns><see langword="true" /> when the cookie does exists, otherwise <see langword="false" />.</returns>
    public static bool Exists(HttpRequestBase request, string name)
    {
        if (request.Cookies[name] != null)
        {
            return true;
        }

        return false;
    }

    #endregion
}

Теперь у меня есть единичный тест, и я хочу проверить свой CookieManager. Здесь единичный тест:

/// <summary>
///     Checks if the repository of the logs does contain an entry.
/// </summary>
[TestMethod]
public void then_the_cookie_should_be_present_in_the_cookiecollection()
{
    var context = new Mock<HttpContextBase>();
    var request = new Mock<HttpRequestBase>();
    var response = new Mock<HttpResponseBase>();

    response.SetupGet(x => x.Cookies).Returns(new HttpCookieCollection());
    request.SetupGet(x => x.Cookies).Returns(response.Object.Cookies);
    context.SetupGet(x => x.Request).Returns(request.Object);
    context.SetupGet(x => x.Response).Returns(response.Object);

    CookieManager.Write(response.Object, "CookieName", "CookieValue");
    var cookie = CookieManager.Read(request.Object, "CookieName", "Default");

    Assert.AreEqual("CookieValue", cookie, "The value retrieved from the cookie is incorrect.");
}

Я знаю, что этот тест работает, но я хочу убедиться, что это правильный способ тестирования или если есть лучшее решение.

Я знаю CodeReview, но я думаю, что вопрос лучше всего здесь. Если нет, мои аплозии.

Теги:
unit-testing

1 ответ

2
Лучший ответ

Тестирование на HttpContextBase сложно, так как оно тесно связано с веб-средой. Таким образом, класс HttpContextBase можно рассматривать как шаблон Humble Object. Это означает, что вам необязательно проверять логику в HttpContextBase.

Чтобы сделать HttpContextBase скромным, вам нужно извлечь абстракцию из логики HttpContextBase следующим образом.

public interface ICookies
{
    string this[string name]{ get; set; }
}

И тогда вы можете создать скромный класс, который не тестируется.

public class Cookies : ICookies
{
    public string this[string name]
    {
        get
        {
            var cookie = HttpContext.Current.Request.Cookies[name];
            if (cookie == null)
                throw new KeyNotFoundException();
            return cookie.Value;
        }
        set
        {
            var cookie = HttpContext.Current.Request.Cookies[name];
            if (cookie == null)
                throw new KeyNotFoundException();
            cookie.Value = value;
        }
    }
}

Ваш целевой класс будет изменен, как показано ниже.

public static class CookieManager
{
    public static void Write(ICookies cookies, string name, string value)
    {
        ...
    }

    ...
}

Это было бы не самое лучшее, но если я попаду в ваше дело, я сделаю вот так.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню