c# - Unit Testing a getter that calls an async operation in a try catch block -
i have following piece of code :
public fuzzypickles(ipie piemaker) { _piemaker = piemaker; } public string piename { { if (_piename == null) { getpiename(); } return _piename; } } private async void getpiename() { string asyncpiename = string.empty; try { var task = _piemaker.getdeliciouspieasync(); asyncpiename = await task; } catch (rottenfruitexception e) { debug.write(e.message); } if (!string.isnullorempty(asyncpiename)) { _piename = asyncpiename; notifypropertychanged(piename); } } and want write test (i using rhinomocks) verify exception thrown in getter won't me pies rotten fruits :
[testclass] public class fuzzytest { private fuzzypickles _pickles; private ipie _piemocker; [testinitialize] public void setup() { _piemocker = mockrepository.mock<ipie>(); _pickles = new fuzzypickles(_piemocker); } [testmethod] public void piename_whengettingexception_shouldhandleexceptiongracefully() { _piemocker.stub(x => x.getdeliciouspieasync()).throws(new rottenfruitexception()); var piename = _pickles.piename; //what should assert here ? } } now here real problem.
removing try / catch block not throw exception ut runner because not use await in ut it's not prototyped async task , getters cannot async, therefore cannot await, or use function instead (or can ?)
that getter bound ui (ie : use display information in ui, don't know when - if ever - called), why i'm doing ugly function call hack, , use notifypropertychanged in (let's not worry cross thread exceptions here, not point)
i not want use code behind hacks (windows phone 8.1 / silverlight project).
how can write unit test fail if remove try / catch block ? should assert on ?
as properties not async compatible (which wise design choice imo), take intializexxxasync pattern mentioned in stephan clearys blog post.
what pattern make invoke initialization method, responsible values creation. if fails, can default default(t), in case of string null, , assert on it:
public class fuzzypickles : inotifypropertychanged { public fuzzypickles(ipie piemaker) { _piemaker = piemaker; } public event propertychangedeventhandler propertychanged; private void onpropertychanged([callermembername] string propertyname = null) { propertychangedeventhandler handler = propertychanged; if (handler != null) handler(this, new propertychangedeventargs(propertyname)); } private string _piename; public string piename { { return _piename; } private set { _piename = value; onpropertychanged() } } public async task initializepieasync() { string asyncpiename = string.empty; try { piename = await _piemaker.getdeliciouspieasync(); } catch (rottenfruitexception e) { debug.write(e.message); } } } now initialize fuzzypickles, initialize , assert isn't null:
[testmethod] public async task piename_whengettingexception_shouldhandleexceptiongracefully() { _piemocker.stub(x => x.getdeliciouspieasync()).throws(new rottenfruitexception()); await _pickles.initializepieasync(); var piename = _pickles.piename; assert.isnotnull(piename); }
Comments
Post a Comment