c# - How do I register decorators with AutoFixture? -


the decorator pattern demonstrates how can extend behaviour of component without modifying underlying implementation. means have 2 components implement same interface. there way register these in autofixture can still refer component polymorphically interface?

a code example my meaning. let's assume want decorate icomponent loggingcomponent

interface icomponent {     void dostuff(); }  class component : icomponent {     public void dostuff()     {         // amazing!     } }  class loggingcomponent : icomponent {     private readonly icomponent _component;      public loggingcomponent(icomponent component)     {         _component = component;     }      public void dostuff()     {         console.writeline("calling dostuff()");         _component.dostuff();     } } 

how go both registering loggingcomponent icomponent , creating loggingcomponent without circular dependency?

what's alternative registering loggingcomponent way:

_fixture.register<icomponent>(_fixture.create<loggingcomponent>); 

and trying create instance of icomponent using code:

var component = _fixture.create<icomponent>(); 

which results in objectcreationexception exception being thrown:

autofixture unable create instance of type ploeh.autofixture.kernel.seededrequest because traversed object graph contains circular reference. information circular path follows below. correct behavior when fixture equipped throwingrecursionbehavior, default. ensures being made aware of circular references in code. first reaction should redesign api in order rid of circular references. however, if not possible (most because parts or of api delivered third party), can replace default behavior different behavior: on fixture instance, remove throwingrecursionbehavior fixture.behaviors, , instead add instance of omitonrecursionbehavior.

you need freeze icomponent first.

then, autofixture re-use same frozen icomponent instance when creating loggingdecorator class.

here 2 ways of doing this:

using autofixture auto mocking:

pm> install-package autofixture.automoq  [fact] public void usingautofixtureautomoq() {     var fixture = new fixture()         .customize(new automoqcustomization());     var expected = fixture.freeze<mock<icomponent>>().object;     var decorator = fixture.create<loggingcomponent>();       var actual = decorator.component;      assert.equal(expected, actual); } 

using autofixture auto mocking , xunit.net data theories:

pm> install-package autofixture.xunit pm> install-package autofixture.automoq  [theory, testconventions] public void usingautofixtureautomoqwithxunittheories(     [frozen]mock<icomponent> inner,     loggingcomponent decorator) {     var expected = inner.object;     var actual = decorator.component;     assert.equal(expected, actual); } 

testconventions attribute class defined as:

internal class testconventionsattribute : autodataattribute {     internal testconventionsattribute()         : base(             new fixture().customize(                 new automoqcustomization()))     {     } } 

note: compile , run above test(s), add inspection property icomponent loggingdecorator.


Comments

Popular posts from this blog

java - Andrioid studio start fail: Fatal error initializing 'null' -

android - Gradle sync Error:Configuration with name 'default' not found -

StringGrid issue in Delphi XE8 firemonkey mobile app -