Как применить настройки AutoFixture ко всему, что наследуется от базового класса?

В попытке высушить мои модульные тесты, я пытаюсь использовать AutoFixture в качестве контейнера IoC для создания экземпляра тестируемой системы (SUT), которые в данном конкретном случае являются ASP.NET MVC. Controllers. Поэтому я хочу настроить AutoFixture для создания контроллеров без авто-свойств.

Я пытался добавить настройки для ControllerBase, но это не похоже на работу для подклассов ControllerBase,

fixture.Customize<ControllerBase>(c => c.OmitAutoProperties());

Вот пример теста, который я хочу написать:

    [Theory, AutoFixtureData]
    public void ControllerTest(AccountController controller) {
        Assert.Equal(default(UrlHelper), controller.Url);
    }

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

1 ответ

Решение

Следующая настройка проходит вышеуказанный тест и выполняет то, что вы, кажется, просите

public class MvcCostumization : ICustomization
{
    public void Customize(IFixture fixture)
    {
        fixture.Customizations.Add(
            new FilteringSpecimenBuilder(
                new MethodInvoker(new ModestConstructorQuery()),
                new ControllerSpecification()));
    }

    private class ControllerSpecification : IRequestSpecification
    {
        public bool IsSatisfiedBy(object request)
        {
            var t = request as Type;
            if (t == null)
                return false;

            return typeof(ControllerBase).IsAssignableFrom(t);
        }
    }
}

Однако это отключает все свойства всех контроллеров MVC, включая User, HttpContext, ModelState, Request, Responseи т. д. Они могут понадобиться в модульных тестах, поэтому вы уверены, что хотите это сделать?

Я буду первым, кто согласится, что MVC Controller Базовый класс - это одно серьезное нарушение SRP, но это класс, который нам дан, поэтому мы ничего не можем с этим поделать, кроме как попытаться извлечь из него максимальную пользу.

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

В проектах MVC 3 этого в сочетании с расширением AutoMoq достаточно для создания экземпляров контроллера:

fixture.Customize<ModelBindingContext>(c => c
    .Without(x => x.Model)
    .Without(x => x.ModelType));
fixture.Inject(CultureInfo.CurrentCulture);
Другие вопросы по тегам