Как применить настройки AutoFixture ко всему, что наследуется от базового класса?
В попытке высушить мои модульные тесты, я пытаюсь использовать AutoFixture в качестве контейнера IoC для создания экземпляра тестируемой системы (SUT), которые в данном конкретном случае являются ASP.NET MVC. Controller
s. Поэтому я хочу настроить 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);