Модульный тест HttpContext. Текущий. Кэш или другие методы серверной стороны в C#?

Поскольку Transaction.create возвращает Promise, вы можете получить setTransferHistory, чтобы это вернуть, и отложить выполнение setWidgetStatus после выполнения обещания setTransferHistory. Таким образом, с:

const setTransferHistory = (
  senderId,
  recipientId,
  amountMoney,
  transferTitle
) =>
  Transaction.create({
    id_sender: senderId,
    id_recipient: recipientId,
    date_time: getTodayDate(),
    amount_money: amountMoney,
    transfer_title: transferTitle
  });

Вы можете иметь:

setTransferHistory(/* args ... */).then(() => {
  setWidgetSatus(senderId);
  setWidgetSatus(recipientId);
});

Или использовать await - это работает с обещанием, как только вы используете его в функции async, [ 1110] не обязательно должен быть асинхронным:

async function foobar() {
  await setTransferHistory(/* args ... */);

  setWidgetSatus(senderId);
  setWidgetSatus(recipientId);
}

Конечно, на данный момент вы можете просто использовать напрямую Transation.create, но вам решать, хотите ли вы добавить слой абстракции. [ 1115]

33
задан Community 23 May 2017 в 12:10
поделиться

10 ответов

Способ сделать это должно избежать прямого использования HttpContext или других подобных классов, и заменить ими с насмешками. В конце концов, Вы не пытаетесь протестировать это, HttpContext функционирует правильно (это - задание Microsoft), Вы просто пытаетесь протестировать это, методы назвали, когда они должны иметь.

Шаги (В случае, если Вы просто хотите знать технику, не роя посредством загрузок блогов):

  1. Создают интерфейс, который описывает методы, которые Вы хотите использовать в своем кэшировании (вероятно, вещи как GetItem, SetItem, ExpireItem). Назовите это ICache или независимо от того, что Вам нравится

  2. , Создают класс, который реализует тот интерфейс и передает методы до реального HttpContext

  3. , Создают класс, который реализует тот же интерфейс и просто действует как ложный кэш. Это может использовать Словарь или что-то, если Вы заботитесь о сохранении объектов

  4. Изменение Ваш исходный код, таким образом, это не использует HttpContext вообще, и вместо этого только когда-либо использует ICache. Код должен будет затем получить экземпляр ICache - можно или передать экземпляр в конструкторе классов (это - весь, что внедрение зависимости действительно), или засуньте его в некоторую глобальную переменную.

  5. В Вашем производственном приложении, набор ICache, чтобы быть Вашим реальным HttpContext-Backed-Cache, и в Ваших модульных тестах, устанавливают ICache, чтобы быть ложным кэшем.

  6. Прибыль!

42
ответ дан 27 November 2019 в 17:32
поделиться

Все эти вопросы о программировании просят основанную на интерфейсе модель программирования, в которой Вы реализуете интерфейс дважды. Один для реального кода и один для макета.

Инстанцирование является затем следующим выпуском. Существует несколько шаблонов разработки, которые могут использоваться для этого. Посмотрите, например, известные шаблоны GangOfFour Creational ( GOF) или шаблоны Внедрения зависимости.

ASP.NET MVC на самом деле использует этот основанный на интерфейсе подход и поэтому намного более подходит для поблочного тестирования.

0
ответ дан 27 November 2019 в 17:32
поделиться

Общее согласие, кажется, что управление чем-либо HttpContext, связанный из модульного теста, является общим кошмаром и должен избежаться, если это возможно.

я думаю, что Вы находитесь на правильном пути относительно насмешки. Мне нравится RhinoMocks ( http://ayende.com/projects/rhino-mocks.aspx ).

я считал некоторые хорошие вещи о MoQ также ( http://code.google.com/p/moq ), хотя я еще не попробовал его.

, Если Вы действительно хотите записать единице тестируемый веб-UIs в C#, путь, люди, кажется, направляются, должен использовать платформу MVC ( http://www.asp.net/mvc ), а не WebForms...

2
ответ дан 27 November 2019 в 17:32
поделиться

Я соглашаюсь с другими, что использование интерфейса было бы наилучшим вариантом, но иногда it’s просто не выполнимый менять существующую систему. Here’s некоторый код, из которого я просто делал пюре вместе из одного из моих проектов, которые должны дать Вам результаты you’re поиск. It’s самая дальняя вещь от симпатичного или отличного решения, но если Вы действительно can’t меняете свой код затем, это должно сделать задание.

using System;
using System.IO;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Web;
using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;

[TestFixture]
public class HttpContextCreation
{
    [Test]
    public void TestCache()
    {
        var context = CreateHttpContext("index.aspx", "http://tempuri.org/index.aspx", null);
        var result = RunInstanceMethod(Thread.CurrentThread, "GetIllogicalCallContext", new object[] { });
        SetPrivateInstanceFieldValue(result, "m_HostContext", context);

        Assert.That(HttpContext.Current.Cache["val"], Is.Null);

        HttpContext.Current.Cache["val"] = "testValue";
        Assert.That(HttpContext.Current.Cache["val"], Is.EqualTo("testValue"));
    }

    private static HttpContext CreateHttpContext(string fileName, string url, string queryString)
    {
        var sb = new StringBuilder();
        var sw = new StringWriter(sb);
        var hres = new HttpResponse(sw);
        var hreq = new HttpRequest(fileName, url, queryString);
        var httpc = new HttpContext(hreq, hres);
        return httpc;
    }

    private static object RunInstanceMethod(object source, string method, object[] objParams)
    {
        var flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
        var type = source.GetType();
        var m = type.GetMethod(method, flags);
        if (m == null)
        {
            throw new ArgumentException(string.Format("There is no method '{0}' for type '{1}'.", method, type));
        }

        var objRet = m.Invoke(source, objParams);
        return objRet;
    }

    public static void SetPrivateInstanceFieldValue(object source, string memberName, object value)
    {
        var field = source.GetType().GetField(memberName, BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance);
        if (field == null)
        {
            throw new ArgumentException(string.Format("Could not find the private instance field '{0}'", memberName));
        }

        field.SetValue(source, value);
    }
}
29
ответ дан 27 November 2019 в 17:32
поделиться

При использовании.NET 3.5 можно использовать Систему. Сеть. Абстракции в Вашем приложении.

у Justin Etheredge есть великое сообщение о том, как дразнить HttpContext (который содержит класс кэша).

От примера Justin, я передаю HttpContextBase своим контроллерам с помощью HttpContextFactory. GetHttpContext. При насмешке их я просто создаю Насмешку для совершения вызовов к объекту кэша.

6
ответ дан 27 November 2019 в 17:32
поделиться

Можно использовать класс HttpContextBase в System.Web.Abstractions.dll. Это - новый dll в.NET 3.5.

Можно найти пример, как использовать в ссылке ниже.

http://vkreynin.wordpress.com/2009/03/23/stub-htttpcontext/

2
ответ дан 27 November 2019 в 17:32
поделиться

Объект кэша сложно имитировать, потому что это закрытая область .NET framework. Обычно я обхожу это путем создания класса оболочки кеша, который принимает объект диспетчера кеша. Для тестирования я использую макет кеш-менеджера; для производства я использую диспетчер кеша, который фактически обращается к HttpRuntime.Cache.

По сути, я сам абстрагирую кеш.

0
ответ дан 27 November 2019 в 17:32
поделиться

Это может быть ваша улица ... Фил Хаак демонстрирует с помощью насмешек Rhino, как имитировать httpcontext в asp mvc, но я полагаю, это можно применить к веб-формам.

Clicky !!

Надеюсь, это поможет.

1
ответ дан 27 November 2019 в 17:32
поделиться

Как все здесь говорили, есть проблема с HTTPContext, в настоящее время Typemock является единственным фреймворк, который может подделать его напрямую, без каких-либо оболочек или абстракций.

0
ответ дан 27 November 2019 в 17:32
поделиться
HttpContext.Current = new HttpContext(new HttpRequest(null, "http://tempuri.org", null), new HttpResponse(null));
17
ответ дан 27 November 2019 в 17:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: