One possibility for handling this case with a minimum of mocking would be to hook do_more so that it calls task.cancel and then calls the regular do_more.
Beyond that it depends on what the actual functions are, I guess. If do_more naturally blocks under some conditions then you might be able to set up those conditions and then call cancel. Or you could try experimenting with tests that call sleep(0) a fixed number of times before issuing the cancel, and repeat with different iteration counts to find different cancel points. (This would benefit from some kind of collaboration with the scheduler, but even a simple hack like this will probably get you more coverage than you had before. It does assume that your test never actually sleeps though.)
-n