c# - Unit testing methods with a local Thread -
i have method looks this:
protected void onbarcodescan(barcodescannereventargs e) { // need on seperate thread don't block main thread. threadstart starter = () => sendscanmessage(e, _scandelegates); thread scanthread = new thread(starter); scanthread.start(); }
then thread goes off , logic (and ends calling delegate in test).
my problem unit test finishes before thread does. test fails.
i can add in system.threading.thread.sleep(1000);
, hope logic never takes more second (it should not). seems hack.
the problem don't want expose thread outside world or rest of class.
is there cool way find thread again , wait in unit test?
something this:
[testmethod] [hosttype("moles")] public void adddelegatetoscanner_scanhappens_scandelegateiscalled() { // arrange bool scancalled = false; mcoredll.gettopwindow = () => (new intptr(fauxhandle)); // act _scanner.adddelegatetoscanner(_formidentity, ((evnt) => { scancalled = true; })); _scanner.sendscan(new barcodescannereventargs("12345678910")); // line fake! system.threading.thread.coolmethodtofindmythread().join(); // assert assert.istrue(scancalled); }
i made coolmethodtofindmythread method. there why that?
so if understand how works, delegates register ones being called on second thread, right? in case, can use thread synchronization in test , delegate gets called. kind of thing in unit tests time.
something this:
[testmethod] [hosttype("moles")] public void adddelegatetoscanner_scanhappens_scandelegateiscalled() { // arrange var scancalledevent = new manualresetevent(false); mcoredll.gettopwindow = () => (new intptr(fauxhandle)); // act _scanner.adddelegatetoscanner(_formidentity, ((evnt) => { scancalledevent.set(); })); _scanner.sendscan(new barcodescannereventargs("12345678910")); // wait event fire bool scancalledintime = scancalledevent.waitone(some_timeout_in_milliseconds); // assert assert.istrue(scancalledintime); }
it's important have some sort of timeout in there, otherwise if goes wrong test locks , that's kind of hard debug. waitone block until event gets set or timeout expires, return value tells happened.
(warning: may have return value backwards - don't remember off top of head if true means event got set or if true means timeout expired. check docs.)
there several sync primitives can use here, 1 depends on want do. manualresetevent works pretty me.
Comments
Post a Comment