فهرست منبع

docs: add page for testing

Mikael Koli 4 سال پیش
والد
کامیت
05689d9b13
2فایلهای تغییر یافته به همراه166 افزوده شده و 0 حذف شده
  1. 1 0
      docs/tutorials/index.rst
  2. 165 0
      docs/tutorials/testing.rst

+ 1 - 0
docs/tutorials/index.rst

@@ -30,4 +30,5 @@ And see - :ref:`cookbook <cookbook>` for example use cases.
    cookbook
    config
    client
+   testing
    example

+ 165 - 0
docs/tutorials/testing.rst

@@ -0,0 +1,165 @@
+
+.. _testing:
+
+How to Test
+===========
+
+For testing purposes, it might be useful to prevent
+sending the actual email. This is especially preferable
+with unit tests. There are several ways to do this.
+
+.. note::
+
+    Red Mail extends :stdlib:`email.message.EmailMessage <email.message.html#email.message.EmailMessage>`
+    from standard library. You may use its attributes and
+    methods for testing the contents of your messages.
+
+Using get_message
+-----------------
+
+All of the arguments in method :py:meth:`.EmailSender.send`
+are passed to :py:meth:`.EmailSender.get_message` method 
+which generates the message itself. Therefore, the simplest
+solution is to use this method instead of :py:meth:`.EmailSender.send`
+in tests:
+
+.. code-block:: python
+
+    from redmail import EmailSender
+
+    # Just put something as host and port
+    email = EmailSender(host="localhost", port=0)
+
+    msg = email.get_message(
+        subject='email subject',
+        sender="me@example.com",
+        receivers=['you@example.com'],
+        text="Hi, this is an email.",
+    )
+
+    assert str(msg) == """from: me@example.com
+    subject: Some news
+    to: you@example.com
+    Content-Type: text/plain; charset="utf-8"
+    Content-Transfer-Encoding: 7bit
+    MIME-Version: 1.0
+
+    Hi, nice to meet you.
+    """
+
+Mock Server
+-----------
+
+In case changing to method :py:meth:`.EmailSender.get_message` 
+is inconvenient or it does not suit to your testing, you may
+also create a mock SMTP server that imitates an actual SMTP
+server instance:
+
+.. code-block:: python
+
+    class MockSMTP:
+
+        messages = []
+
+        def __init__(self, host, port):
+            self.host = host
+            self.port = port
+
+        def starttls(self):
+            # Called only if use_startls is True
+            return
+
+        def login(self, username, password):
+            # Log in to the server (if credentials passed)
+            self.username = username
+            self.password = password
+            return
+
+        def send_message(self, msg):
+            # Instead of sending, we just store the message
+            self.messages.append(msg)
+
+        def quit(self):
+            # Closing the connection
+            return
+
+Then to use this mock:
+
+.. code-block:: python
+
+    from redmail import EmailSender
+
+    email = EmailSender(
+        host="localhost", 
+        port=0, 
+        username="me@example.com", 
+        password="1234", 
+        cls_smtp=MockServer
+    )
+
+    email.send(
+        subject='email subject',
+        sender="me@example.com",
+        receivers=['you@example.com'],
+        text="Hi, this is an email.",
+    )
+
+    msgs = MockServer.messages
+    assert msgs == 
+    ["""from: me@example.com
+    subject: Some news
+    to: you@example.com
+    Content-Type: text/plain; charset="utf-8"
+    Content-Transfer-Encoding: 7bit
+    MIME-Version: 1.0
+
+    Hi, nice to meet you.
+    """]
+
+Note that an instance of ``MockServer`` is created 
+for each connection, often per sent email.
+
+Subclass Sender
+---------------
+
+Another option is to just subclass the sender and 
+change the email sending there:
+
+.. code-block:: python
+
+    from redmail import EmailSender
+
+    class MockSender(EmailSender):
+
+        def __init__(self, *args, **kwargs):
+            super().__init__(*args, **kwargs)
+            self.messages = []
+
+        def send_message(self, msg):
+            self.messages.append(msg)
+
+Then to use this class:
+
+.. code-block:: python
+
+    # Just put something as host and port
+    email = MockSender(host="localhost", port=0)
+
+    email.send(
+        subject='email subject',
+        sender="me@example.com",
+        receivers=['you@example.com'],
+        text="Hi, this is an email.",
+    )
+
+    msgs = email.messages
+    assert msgs == 
+    ["""from: me@example.com
+    subject: Some news
+    to: you@example.com
+    Content-Type: text/plain; charset="utf-8"
+    Content-Transfer-Encoding: 7bit
+    MIME-Version: 1.0
+
+    Hi, nice to meet you.
+    """]