c# - Testing Event driven behavior -


there seems ton of advice sorta thing in context of gui application. think particular scenario different enough warrent me asking. sum question how test events?

now long winded explanation. i've worked point of service hardware little while now. means had write few opos service objects. after few years of doing managed write first com visible c# service object , put production. tried best unit test entire project found rather difficult, able come unit tests of service object's interface implementation. hardest part event's part. granted scenario biggest , common 1 faced, i've come across similar scenarios in other applications of mine testing event seemed awkward. set scene common control object (co) has @ 5 events person can subscribe too. when co calls method open opos finds service object (so) , creates instance of it, calls it's openservice method. third parameter of reference co. don't have define entire co, have define call method 5 events. example of msr's definition this

[comimport, interfacetype(cominterfacetype.interfaceisdual), guid("ccb91121-b81e-11d2-ab74-0040054c3719")] internal interface msrcontrolobject {     [dispid(1)]     void sodata(int status);      [dispid(2)]     void sodirectio(int eventnumber, ref int pdata, ref string pstring);      [dispid(3)]     void soerror(int resultcode, int resultcodeextended, int errorlocus, ref int perrorresponse);      [dispid(4)]     void sooutputcompletedummy(int outputid);      [dispid(5)]     void sostatusupdate(int data); }  

and openservice method have line of code

public class fakemsrserviceobject : iuposbase {     msrcontrolobject _controlobject;     public int openservice(string deviceclass, string devicename, object dispatchobject)     {         _controlobject = (msrcontrolobject)dispatchobject;     }     //example of how fire event      private void firedataevent(int status)     {         _controlobject.sodataevent(status);     } } 

so thought myself better testing, lets make controlobjectdispatcher. allow me enqueue events, fire them co when conditions correct. i'm at. know sorta how test drive implementation of it. feels wrong. lets take dataevent example. 2 conditions have met dataevent fired. first boolean property dataeventenabled must true, , other boolean property freezeevents must false. events strictly fifo. so.. queue perfect. , since i've written before know implementation be. writing test instills confidence new person project difficult. consider pseudo code

[test] public void whenmultipleeventsarequeuedtheyarefiredsequentiallywhenconditionsarecorrect() {     _dispatcher.enqueuedataevent(new dataevent(42));     _dispatcher.enqueuestatusupdateevent(new statusupdateevent(1));      sleep(1000);     _spy.assertnoeventshavefired();     _spy.asserteventscount(2);      _serviceobject.setnumericproperty(pidx_dataeventenabled, 1);      _spy.assertdataeventfired();     _spy.assertstatusupdateeventfired();      _serviceobject.getnumericproperty(pidx_dataeventenabled).should().beequalto(0, "because firing dataevent sets dataeventenabled false"); } 

everyone reading hear wonder (without knowing implementation) how know after 1 minute event fires? how know that crazy robert snyder person didn't use loop , forget exit firedataevent routine after iterations up? don't. granted test minute.. defeats purpose of unit test.

so sum again... how person write test events? events can fire whenever.. , can take longer process , fire expected. i've seen in integration tests first implementation of if didn't sleep 50ms before asserting event called test fail like. expected data event have fired, never fired test frameworks built events? common coding practices cover this?

it’s bit unclear if you’re looking unit testing or integration testing events, since talk both. however, given tags on question, i’m going assume primary interest unit testing perspective. unit testing perspective doesn’t make difference if testing event, or normal method. goal of unit test individual chunks of functionality in isolation, whilst having sleep in integration test might make sense (although i’d still try avoid , use other kind of synchronisation possible), in unit test i’d take flag functionality being tested hasn’t been isolated sufficiently.

so, me, there’s 2 slices of event driven testing. firstly want test events class fires fired when appropriate conditions met. secondly want test handlers events perform expected actions.

testing handlers behave expected should similar other test right. setup handler expected state, set expectations, call if event generator , verify relevant behaviour.

testing events fired same, setup state expect fire event, , verify appropriately populated event fired , other state change takes place. so, looking @ pseudo code, have @ least 2 tests:

// setup (used both tests) // test may missing setup dispatcher state == data event disabled.     _dispatcher.enqueuedataevent(new dataevent(42));     _dispatcher.enqueuestatusupdateevent(new statusupdateevent(1));  //    sleep(1000);    // shouldn’t in unit test.  // test 1 – verifythatdataandstatuseventsdonotfirewhendataeventdisabled     _spy.assertnoeventshavefired();     _spy.asserteventscount(2);  // test 2 – verifythatenablingdataeventfirespendingdataevents     _serviceobject.setnumericproperty(pidx_dataeventenabled, 1);      _spy.assertdataeventfired();     _spy.assertstatusupdateeventfired();  // test 3? – part of test 2, or different test verifythatdataeventsaredisabledonceadataeventhasbeentriggered.     _serviceobject.getnumericproperty(pidx_dataeventenabled).should().beequalto(0, "because firing dataevent sets dataeventenabled false"); 

looking @ test code, there isn’t suggest you’ve implemented actual serviceobject using kind of loop, or minute of testing have impact on behaviour of serviceobject. if weren’t thinking perspective of event programming considering if calling setnumericproperty result in using ‘a loop , forgeting exit firedataevent routine after iterations up?’ seems if that’s case either setnumericproperty wouldn’t return or have non-linear implementation , you’re possibly testing wrong thing in wrong place. without seeing event generation code it’s hard advise on though…

events can fire whenever… , can take longer process , fire expected

whilst may true when application running, shouldn’t true when you’re doing unit testing. unit tests should trigger events defined conditions , test events have been triggered , been generated correctly. achieve need aim unit isolation , may have accept thin elements need integration tested, rather unit tested in order achieve isolation. if dealing events triggered outside app may end this:

public interface iinternaleventprocessor {     void sodata(int status);     void sodirectio(int eventnumber, int pdata, string pstring); };  public class externaleventprocessor {     iinternaleventprocessor _internalprocessor;      public externaleventprocessor(iinternaleventprocessor internalprocessor, /*ideally pass in interface external system allow unit testing*/) {         _internalprocessor = internalprocessor;         // register event subscriptions external system     }      public void sodata(int status) {         _internalprocessor.sodata(status);     }      void sodirectio(int eventnumber, ref int pdata, ref string pstring) {         _internalprocessor.sodirectio(eventnumber, pdata, pstring);     } } 

the purpose of externaleventprocessor decouple dependency on external system unit testing of event handling in internaleventprocessor easier. ideally, still able unit test externaleventprocessor registers events correctly , passes through supplying mocks of external system , internal implementation, if can’t because class cut down bare minimum having integration testing class might realistic option.


Popular posts from this blog