J'essaie de générer des sous-classes d'ApiController (WebAPI 2) en utilisant AutoFixture (3.50.6).Pourquoi ai-je une référence circulaire DummyApiController -> DummyApiController lorsque j'utilise un constructeur d'échantillons?
J'ai AF personnalisé pour permettre de générer ApiControllers en utilisant this customization.
En raison des besoins supplémentaires de personnalisation, je voudrais créer un SpecimenBuilder
qui créerait tout type de ApiController et d'appliquer cette configuration avec un simple
fixture.Create<DummyController>();
J'ai essayé ce test (NUnit 3):
[TestFixture]
public class ApiControllerSpecimenBuilderTests
{
[Test]
public void ShouldCreateAControllerUsingSpecimenBuilder()
{
var fixture = new Fixture()
.Customize(new AutoMoqCustomization())
.Customize(new ApiControllerCustomization());
fixture.Customizations.Add(new ApiControllerSpecimenBuilder());
var ctl = fixture.Create<DummyController>();
}
}
public class ApiControllerCustomization : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Inject(new UriScheme("http"));
fixture.Customize<HttpConfiguration>(c => c
.OmitAutoProperties());
fixture.Customize<HttpRequestMessage>(c => c
.Do(x =>
x.Properties.Add(
HttpPropertyKeys.HttpConfigurationKey,
fixture.Create<HttpConfiguration>())));
fixture.Customize<HttpRequestContext>(c => c
.Without(x => x.ClientCertificate));
}
}
public class ApiControllerSpecimenBuilder : ISpecimenBuilder
{
public object Create(object request, ISpecimenContext context)
{
var t = request as Type;
if (t == null || !typeof(ApiController).IsAssignableFrom(t))
{
return new NoSpecimen();
}
var controller = context.Resolve(t) as ApiController;
// ...
return controller;
}
}
public class DummyController : ApiController
{
}
qui échoue avec l'erreur suivante:
Ploeh.AutoFixture.Object CreationException: AutoFixture n'a pas pu créer une instance de type System.RuntimeType, car le graphique objet traversé contient une référence circulaire. [...]
Chemin: Foo.Common.Tests.AutoFixture.SpecimenBuilders.DummyController -> Foo.Common.Tests.AutoFixture.SpecimenBuilders.DummyController
Pourquoi le DummyController ont une référence à son propre type?
De plus, si je change le test avec une personnalisation vide pour DummyController, il passe:
[Test]
public void ShouldCreateAControllerUsingSpecimenBuilder()
{
var fixture = new Fixture()
.Customize(new AutoMoqCustomization())
.Customize(new ApiControllerCustomization())
.Customize(new DummyControllerCustomization()); // new customization
fixture.Customizations.Add(new ApiControllerSpecimenBuilder());
var ctl = fixture.Create<DummyController>();
}
public class DummyControllerCustomization : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Customize<DummyController>(c => c);
}
}
Dans ce cas, le SpecimenBuilder semble ne pas être plus touché avec le type DummyController. Que fait cette personnalisation vide qui fait passer le test? Surclasse-t-il le constructeur de spécimens? Mais alors pourquoi ne lance-t-il pas la même exception, puisque je ne lui dis pas d'omettre quoi que ce soit (et de toute façon, je ne saurais pas quoi faire pour l'omettre ...)? Je suppose que je pourrais utiliser le OmitOnRecursionBehavior
, mais je voudrais garder le comportement par défaut pour éviter les récursions dans tous les autres cas, et je comprendrais plutôt ce qui se passe (ou si j'ai vraiment mal fait).
Question parfaite: j'ai eu un repro en une tentative. Bon travail :) –