I would think the real answer depends on how critical it is that the email gets sent once and how much error checking you want to do. Let me explain:
We have a system for incident reporting that sends an email when an incident is entered. Not realizing the volume of emails we would have it originally just sent off a batch of 100 at a time (SMTP limits) and loped through groups if there was more than that- after some sales we found that upwards of a few 1000 were being sent on each entry and it could take almost a minute to send them all - creating a mail thread was not a real good match for this so we created a mail que and had a job loop through those every 5 minutes and send any that hadnt been sent - mistake - if the que got held up or if there were so many emails in the que that it took longer than 5 minutes to run it would start again and we had some emails getting sent 2, 3 4, even 10 times - might have been bad design but whatever
We finaly just moved the whole thing to SQL Servers mail que and it has been running like a champ - the real lesson (in my opinion is) is do all the processing however you need to into your program but once you know the emails are to be sent and to whom pass that off to something that specifically handles email sending (CDO, Sql Server mail , Oracle whatever)
You can still test all the logic you want in your app but let the email be taken care of by something built to handle email.