Модульное тестирование всех контроллеров из одного теста

Я только что создал фильтр действий, который хочу применить почти ко всем своим контроллерам (включая любые новые, которые появятся позже).

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

Разумно ли создавать модульный тест, который затрагивает несколько контроллеров? Может ли кто-нибудь поделиться кодом из аналогичного теста, который оказался полезным?

РЕДАКТИРОВАТЬ: только что понял, что тестирование фильтра действий может быть проблемным. Тем не менее, если есть мысли поделиться по поводу массового тестирования контроллеров ...


person Mayo    schedule 22.09.2010    source источник


Ответы (3)


Не рекомендуется тестировать в тестах более одного объекта одновременно.

Вам также следует избегать логики в тестах (переключение, if, else, foreach, for, while), поскольку тест менее читабелен и, возможно, содержит скрытые ошибки.

Многие простые, удобочитаемые и, следовательно, поддерживаемые тесты, каждый из которых тестирует только одну вещь, намного предпочтительнее одного теста с большой сложностью.

ОТВЕТ НА ВАШЕ РЕДАКТИРОВАНИЕ

Фильтры можно проверить, отделив фильтр от атрибута. Вот пример: класс LoadMembershipTypeListFilter имеет «швы», необходимые для использования тестовых подделок. Вот где ваша логика в вашем фильтре должна быть проверена.

public class LoadMembershipTypeListFilter : IActionFilter
{
    private IMembershipTypeProvider _provider;
    private IMembershipTypeAdminMapper _mapper;

    public LoadMembershipTypeListFilter(IMembershipTypeProvider provider, IMembershipTypeAdminMapper mapper)
    {
        _provider = provider;
        _mapper = mapper;
    }

    #region IActionFilter Members
    public void OnActionExecuted(ActionExecutedContext filterContext)
    {
    }

    public void OnActionExecuting(ActionExecutingContext filterContext)
    {
        //implementation...
    }
    #endregion
}

И атрибут здесь использует фильтр, этот пример разрешает зависимости, требуемые фильтром, путем вызова локатора службы:

public class LoadMembershipTypeListAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var filter = new LoadMembershipTypeListFilter(IocResolve.Resolve<IMembershipTypeProvider>(), IocResolve.Resolve<IMembershipTypeAdminMapper>());
        filter.OnActionExecuting(filterContext);
    }
}

И ваш контроллер использует атрибут:

[LoadMembershipTypeList]
public ActionResult Create()
{
    return View();
}
person CRice    schedule 22.09.2010

Поскольку вы, скорее всего, в любом случае собираетесь писать модульные тесты для каждого контроллера, у вас всегда может быть просто базовый класс модульного теста, который проверяет фильтр действий. Любой тест контроллера, использующий фильтр действий, будет унаследован от этого класса, чтобы также проверить фильтр действий.

person Todd    schedule 22.09.2010

Я бы сказал, что на этом этапе вы тестируете инфраструктуру. Если вы хотите проверить, применяются ли фильтры в ожидаемых вами методах, используйте отражение + сопоставьте список методов, которые, как вы ожидаете, будут сопоставлены.

Может быть, вы хотите проверить, что у методов есть определенная подпись, для этого также подойдет вышеприведенное.

Если вы хотите протестировать фильтр действий, идите прямо против него. Возможно, вам действительно нужно убедиться, что с фильтром работают разные результаты / модели.

person eglasius    schedule 22.09.2010