2014-09-16 11 views
5

Używam AutoFixture i chciałbym użyć konkretnego konstruktora.Wybierz konkretnego konstruktora z AutoFixture

Mam następujący kod i lubię wybrać konstruktora z ITemplateParameterHandler.

public sealed class TemplateSegmentHandler : ITemplateSegmentHandler 
{ 
    public TemplateSegmentHandler(ITemplateIterator iterator) 
     : this(new TemplateParameterHandler(iterator)) 
    { 
     Contract.Requires(iterator != null); 
    } 

    public TemplateSegmentHandler(ITemplateParameterHandler parameterHandler) 
    { 
     Contract.Requires(parameterHandler != null); 

     _parameterHandler = parameterHandler; 

     _parameterHandler.Ending += EndingParameter; 
    } 

    // ... 
} 

EDIT:

Chcę wprowadzić następujące fałszywy realizację. (Używam NSubstitute do tworzenia fałszywego obiektu.)

public sealed class CustomTemplateParameter : ICustomization 
{ 
    private readonly ITemplateParameterHandler _context; 

    public CustomTemplateParameter() 
    { 
     _context = Substitute.For<ITemplateParameterHandler>(); 
    } 

    public void Customize(IFixture fixture) 
    { 
     fixture.Customize<ITemplateParameterHandler>(c => c.FromFactory(() => _context)); 
    } 

    public CustomTemplateParameter SetCatchAll(bool isCatchAll) 
    { 
     _context.IsCatchAll.Returns(isCatchAll); 

     return this; 
    } 
} 

Oto sposób, w jaki próbuję go użyć.

[Fact] 
public void Should_return_true_when_the_segment_has_a_catch_all_parameter() 
{ 
    TemplateSegmentHandler segmentHandler = new Fixture().Customize(new TemplateSegmentHandlerFixture()) 
                 .Customize(new CustomTemplateParameterHandler() 
                     .SetCatchAll(true)) 
                 .Create<TemplateSegmentHandler>(); 

    segmentHandler.Parameter.Start(); 
    segmentHandler.Parameter.End(); 

    segmentHandler.HasCatchAll.Should().BeTrue(); 
} 

Ale to nadal wybiera niewłaściwy konstruktora, a ja otrzymuję następujący błąd.

Ploeh.AutoFixture.ObjectCreationExceptionAutoFixture was unable to create an instance from Somia.Web.Routing.Template.ITemplateIterator, most likely because it has no public constructor, is an abstract or non-public type. 

Request path: 
     Somia.Web.Routing.Template.TemplateSegmentHandler --> 
     Somia.Web.Routing.Template.ITemplateIterator iterator --> 
     Somia.Web.Routing.Template.ITemplateIterator 

Odpowiedz

4

skończyło się na wdrażaniu IMethodQuery i wybierz konstruktor chciałem.

public sealed class SelectedFirstConstructorQuery : IMethodQuery 
{ 
    private readonly Type _type; 

    public SelectedFirstConstructorQuery(Type type) 
    { 
     _type = type; 
    } 

    public IEnumerable<IMethod> SelectMethods(Type type) 
    { 
     if (type == null) 
     { 
      throw new ArgumentNullException("type"); 
     } 

     return from ci in type.GetConstructors() 
       let parameter = ci.GetParameters().First() 
       where parameter.ParameterType == _type 
       select new ConstructorMethod(ci) as IMethod; 
    } 
} 

Zastosowanie:

fixture.Customize<TemplateSegmentHandler>(c => c.FromFactory(new MethodInvoker(new SelectedFirstConstructorQuery(typeof(ITemplateParameterHandler))))); 
1

Jednym z możliwych sposobów:

var parameterHandler = fixture.Create<ITemplateParameterHandler>(); 

var segmentHandler = fixture.Build<TemplateSegmentHandler>() 
          .FromFactory(() => new TemplateSegmentHandler(parameterHandler)); 

fixture.Inject(segmentHandler); 
+0

Tak, przepraszam, że nie pisał go w moim OP, ale chcę, aby wprowadzić własny obiekt, będę aktualizować mój post z większą ilością szczegółów. –

Powiązane problemy