c# - AutoMocking Properties Fails on Abstract Property? -
c# - AutoMocking Properties Fails on Abstract Property? -
i'm trying larn autofixture, , i've got xunit , nsubstitute , autofixture setup automatically mock out properties fakes (with autofixture.autonsubstitute). in other words, if have next interface
public interface ifoo { ibar1 bar1 {get;} ibar2 bar2 {get; set;} } trying resolve ifoo automatically resolve , populate bar1 , bar2.
everything works great objects properties of interface, concrete object, or construction types. i'm having problem getting autofixture automatically create properties of abstract types however.
i have tried using typerelay abstract type, so
fixture.customizations.add(new typerelay(typeof (abstractbase), typeof (concretechild))); i have tried specifying way,
fixture.customize<abstractbase>( composer => composer.fromfactory( (string childparam1, string childparam2) => new concretechild(concretechildparam1, concretechildparam2))); i have tried using various custom specimen builders
resolving via property type:
var pi = request propertyinfo; if (pi != null && pi.propertytype == typeof(abstractbase)) homecoming context.resolve(typeof(concretechild)); homecoming new nospecimen(request); resolving via class type:
var pi = request type; if (pi != null && pi == typeof (abstractbase)) homecoming context.resolve(typeof(concretechild)); homecoming new nospecimen(request); with both of above solutions, tried context.create<concretechild>()
finally have tried using register<abstractbase>(fixture.create<concretechild>); syntax.
none of them seem work far automatically populating properties on object.
the irritating thing can explicitly fixture.create<abstractbase>(); in individual test , concretechild , hand-jam kind of defeats purpose of autofixture no?
any ideas?
update:
the abstract class. i've pruned of irrelivent stuff, left ctor code in i'm assuming gets called?
public abstract class chatentityid { private string _localname; protected chatentityid(string chatroomname, string entityuid, chatprotocol protocol) { errorchecker.normalizetonullifnotset(ref chatroomname); errorchecker.normalizetonullifnotset(ref entityuid); if (chatroomname == null && entityuid == null) { throw new argumentexception("both chatroomname , entityuid may not null @ same time."); } chatroomname = chatroomname; entityuid = entityuid; protocol = protocol; } public string chatroomname { get; private set; } public string entityuid { get; private set; } public bool equals(chatentityid chatentityid) { } public override bool equals(object obj) { } public override int gethashcode() {} public string localname { get; } public chatprotocol protocol { get; private set; } public override string tostring() { } } chatprotocol enum, standard.
the autopopulatedproperty icustomization
public virtual void customize(ifixture fixture) { fixture.customize(new domaincustomization()); // replacement autonsubstitutecustomization, postprocessor automatically create false objects on properties. fixture.residuecollectors.add( new postprocessor( new nsubstitutebuilder( new methodinvoker( new nsubstitutemethodquery())), new autopropertiescommand( new propertiesonlyspecification()))); } private class propertiesonlyspecification : irequestspecification { public bool issatisfiedby(object request) { homecoming request propertyinfo; } }
somewhat embarrassingly, realized nsubstitute has calls recursive mocking, partially want , explains why couldn't figure out of auto-mocked properties coming from. problem doesn't across board (probably rightfully so), , isn't extensible in regard far can tell.
now autofixture comes play, after create specimen in postprocessors nsubstitutebuilder, autopropertiescommand class called , fetches determines appropriate properties populate data.
unfortunately none of logic in 2 relevant classes (there non-generic inheriting generic autopropertiescommand class) overridable , problem occurs. specifically, autopropertiescommand<t> has 2 methods uses properties , fields, filters using supplied irequestspecification (propertiesonlyspecification in case).
the method in question
private ienumerable<propertyinfo> getproperties(object specimen) { homecoming pi in this.getspecimentype(specimen).getproperties(bindingflags.public | bindingflags.instance) pi.getsetmethod() != null && pi.getindexparameters().length == 0 && this.specification.issatisfiedby(pi) select pi; } so solution here either provide own autopropertiescommand implementation without above limitations or explicitly create customizations each case run across. haven't decided approach improve former.
as side-bar seems kind of restrictive not have 2 methods protected virtual, there particular reason beyond "it coded way"? base of operations autofixture classes believe, record.
c# xunit.net autofixture nsubstitute
Comments
Post a Comment