1

I have a library which has many async parts to it, and testing a specific part of it can sometimes mean waiting for n asynchronous processes to complete before the test is available to actually be run. I have been using this method to achieve my purposes:

void expectAsyncWithReadyCheckAndTimeout(bool readyCheck(), int timeout, void expect()){
  DateTime start = new DateTime.now();
  Duration limit = new Duration(seconds: timeout);
  var inner;
  inner = (){
    if(readyCheck()){
      expect();
    }else if(new DateTime.now().subtract(limit).isAfter(start)){
      throw 'async test timed out';
    }else{
      Timer.run(expectAsync(inner));
    }
  };
  inner();
}

this basically keeps running until either the test is ready to be run or until some specified timeout expires, is there a way of achieving this or something similar directly with the dart unittest library?

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
Daniel Robinson
  • 13,806
  • 18
  • 64
  • 112

2 Answers2

1

What I usually do is to make a single "done" function with expectAsync, and I then call that function when the complex test is complete.

testFoo() { 
  var done = expectAsync((){});
  someComplexTest(....
     ...
     if (eveerythingOk) done();
     ..
  )
}

That is: create the expectAsync wrapped function up-front, and call it when you think the test is completed successfully - handle everything else manually.

lrn
  • 64,680
  • 7
  • 105
  • 121
0

You can add an optional parameter to expectAsync that says how often the method needs to be called.

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • doesnt that argument just tell it it needs to be called N times? I dont understand why anyone would want to do that, I just want my asynchronous test to run once when all my other asynchronous process have completed and the test is ready, but I dont know how many asynchronous process there are to complete before the test is ready, it might be anywhere between 1 and 20 typically. – Daniel Robinson Apr 26 '14 at 20:40
  • That's was it does. Seems I didn't understand your question. – Günter Zöchbauer Apr 26 '14 at 20:41
  • well, lets say, I call `expectAsync((){/*expectStuff*/}, count: 4)` won't this `expectStuff` 4 times? and if my async processes haven't completed yet all 4 times it `expectsStuff` it will fail won't it? or if it only `expectsStuff` on the last execution, I don't know that my test encompasses 4 asynchronous processes, it could be any number of asynchrononous process chained together, so again the test will fail if its waiting on 5 or more asynchronous chain calls won't it? – Daniel Robinson Apr 26 '14 at 20:47
  • Can you create one `expectAsync` for each async process when you create them? – Günter Zöchbauer Apr 26 '14 at 20:50
  • well I'm basically creating full end to end tests for a full web stack, the test starts out by calling a method on a view, which then async calls to the server, which then might do any number of async calls to services and databases etc, before finally returning a response to the view and updating itself. The `expectAsyncWithReadyCheckAndTimeout` satisfies my needs because it will evaluate once any number of async processes have completed provided its within the timeout limit which is just there as a precaution so tests aren't allowed to run on forever. I just hoped there might be a built in – Daniel Robinson Apr 26 '14 at 20:58
  • method to achieve the same effect, or an alternative approach I haven't thought of, your suggestion of expectAsync after each async process starts is a good idea but not open to me as the test only has access to the view and must wait for the view to update itself after the web servers response – Daniel Robinson Apr 26 '14 at 20:59