I'm a newbie to python and the app engine.
I have this code that sends an email based on request params after some auth logic. in my Unit tests (i'm using GAEUnit), how do I confirm an email with specific contents were sent? - i.e. how do I mock the emailer with a fake emailer to verify send was called?
class EmailHandler(webapp.RequestHandler):
 def bad_input(self):
  self.response.set_status(400)
  self.response.headers['Content-Type'] = 'text/plain'
  self.response.out.write("<html><body>bad input </body></html>")
 def get(self):
  to_addr = self.request.get("to")
  subj = self.request.get("subject")
  msg = self.request.get("body")
  if not mail.is_email_valid(to_addr):
    # Return an error message...
    #   self.bad_input()
    pass
  # authenticate here
  message = mail.EmailMessage()
  message.sender = "[email protected]"
  message.to = to_addr
  message.subject = subj
  message.body = msg
  message.send()
  self.response.headers['Content-Type'] = 'text/plain'
  self.response.out.write("<html><body>success!</body></html>")
And the unit tests,
import unittest
from webtest import TestApp
from google.appengine.ext import webapp
from email import EmailHandler
class SendingEmails(unittest.TestCase):
  def setUp(self):
    self.application = webapp.WSGIApplication([('/', EmailHandler)], debug=True)
  def test_success(self):
    app = TestApp(self.application)
    response = app.get('http://localhost:8080/[email protected]&body=blah_blah_blah&subject=mySubject')
    self.assertEqual('200 OK', response.status)
    self.assertTrue('success' in response)
    # somehow, assert email was sent 
                You could also override the _GenerateLog method in the mail_stub inside AppEngine.
Here is a parent TestCase class that I use as a mixin when testing that e-mails are sent:
from google.appengine.api import apiproxy_stub_map, mail_stub
__all__ = ['MailTestCase']
class MailTestCase(object):
    def setUp(self):
        super(MailTestCase, self).setUp()
        self.set_mail_stub()
        self.clear_sent_messages()
    def set_mail_stub(self):
        test_case = self
        class MailStub(mail_stub.MailServiceStub):
            def _GenerateLog(self, method, message, log, *args, **kwargs):
                test_case._sent_messages.append(message)
                return super(MailStub, self)._GenerateLog(method, message, log, *args, **kwargs)
        if 'mail' in apiproxy_stub_map.apiproxy._APIProxyStubMap__stub_map:
            del apiproxy_stub_map.apiproxy._APIProxyStubMap__stub_map['mail']
        apiproxy_stub_map.apiproxy.RegisterStub('mail', MailStub())
    def clear_sent_messages(self):
        self._sent_messages = []
    def get_sent_messages(self):
        return self._sent_messages
    def assertEmailSent(self, to=None, sender=None, subject=None, body=None):
        for message in self.get_sent_messages():
            if to and to not in message.to_list(): continue
            if sender and sender != message.sender(): continue
            if subject and subject != message.subject(): continue
            if body and body not in message.textbody(): continue
            return
        failure_message = "Expected e-mail message sent."
        args = []
        if to: args.append('To: %s' % to)
        if sender: args.append('From: %s' % sender)
        if subject: args.append('Subject: %s' % subject)
        if body: args.append('Body (contains): %s' % body)
        if args:
            failure_message += ' Arguments expected: ' + ', '.join(args)
        self.fail(failure_message)
After that, a sample test case might look like:
import unittest, MailTestCase
class MyTestCase(unittest.TestCase, MailTestCase):
    def test_email_sent(self):
        send_email_to('[email protected]') # Some method that would send an e-mail.
        self.assertEmailSent(to='[email protected]')
        self.assertEqual(len(self.get_sent_messages()), 1)
                        A very short introduction provides PyPI: MiniMock 1.0. It's a very small library to establish mocks.
Good luck!
Just use the following to get all messages sent since activating the mail stub.
from google.appengine.api import apiproxy_stub_map
sent_messages = apiproxy_stub_map.apiproxy._APIProxyStubMap__stub_map['mail'].get_sent_messages()
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With